PEP8 cleanup of the entire codebase. Unchanged are many cases of too-long lines, partly because of the rewrite they would require but also because splitting many lines up would make the code harder to read. Also the third-party libraries (idmapper, prettytable etc) were not cleaned.

This commit is contained in:
Griatch 2013-11-14 19:31:17 +01:00
parent 30b7d2a405
commit 1ae17bcbe4
154 changed files with 5613 additions and 4054 deletions

View file

@ -0,0 +1 @@
# -*- coding: utf-8 -*-

View file

@ -20,12 +20,14 @@ import zlib
MCCP = chr(86)
FLUSH = zlib.Z_SYNC_FLUSH
def mccp_compress(protocol, data):
"Handles zlib compression, if applicable"
if hasattr(protocol, 'zlib'):
return protocol.zlib.compress(data) + protocol.zlib.flush(FLUSH)
return data
class Mccp(object):
"""
Implements the MCCP protocol. Add this to a

View file

@ -9,9 +9,7 @@ etc.
"""
import re
from django.conf import settings
from src.utils.utils import make_iter, mod_import, to_str
from src.utils import logger
from src.utils.utils import to_str
# MSDP-relevant telnet cmd/opt-codes
MSDP = chr(69)
@ -29,11 +27,18 @@ SE = chr(240)
force_str = lambda inp: to_str(inp, force_string=True)
# pre-compiled regexes
regex_array = re.compile(r"%s(.*?)%s%s(.*?)%s" % (MSDP_VAR, MSDP_VAL, MSDP_ARRAY_OPEN, MSDP_ARRAY_CLOSE)) # return 2-tuple
regex_table = re.compile(r"%s(.*?)%s%s(.*?)%s" % (MSDP_VAR, MSDP_VAL, MSDP_TABLE_OPEN, MSDP_TABLE_CLOSE)) # return 2-tuple (may be nested)
# returns 2-tuple
regex_array = re.compile(r"%s(.*?)%s%s(.*?)%s" % (MSDP_VAR, MSDP_VAL,
MSDP_ARRAY_OPEN,
MSDP_ARRAY_CLOSE))
# returns 2-tuple (may be nested)
regex_table = re.compile(r"%s(.*?)%s%s(.*?)%s" % (MSDP_VAR, MSDP_VAL,
MSDP_TABLE_OPEN,
MSDP_TABLE_CLOSE))
regex_var = re.compile(MSDP_VAR)
regex_val = re.compile(MSDP_VAL)
# Msdp object handler
class Msdp(object):
@ -90,7 +95,7 @@ class Msdp(object):
else:
string += MSDP_VAR + force_str(key) + MSDP_VAL + force_str(val)
string += MSDP_TABLE_CLOSE
return stringk
return string
def make_array(name, *args):
"build a array. Arrays may not nest tables by definition."
@ -169,7 +174,7 @@ class Msdp(object):
tables[key] = {}
for varval in regex_var.split(table):
parts = regex_val.split(varval)
tables[key].expand({parts[0] : tuple(parts[1:]) if len(parts)>1 else ("",)})
tables[key].expand({parts[0]: tuple(parts[1:]) if len(parts) > 1 else ("",)})
for key, array in regex_array.findall(data):
arrays[key] = []
for val in regex_val.split(array):
@ -178,16 +183,18 @@ class Msdp(object):
for varval in regex_var.split(regex_array.sub("", regex_table.sub("", data))):
# get remaining varvals after cleaning away tables/arrays
parts = regex_val.split(varval)
variables[parts[0].upper()] = tuple(parts[1:]) if len(parts)>1 else ("", )
variables[parts[0].upper()] = tuple(parts[1:]) if len(parts) > 1 else ("", )
#print "MSDP: table, array, variables:", tables, arrays, variables
# all variables sent through msdp to Evennia are considered commands with arguments.
# there are three forms of commands possible through msdp:
# all variables sent through msdp to Evennia are considered commands
# with arguments. There are three forms of commands possible
# through msdp:
#
# VARNAME VAR -> varname(var)
# ARRAYNAME VAR VAL VAR VAL VAR VAL ENDARRAY -> arrayname(val,val,val)
# TABLENAME TABLE VARNAME VAL VARNAME VAL ENDTABLE -> tablename(varname=val, varname=val)
# TABLENAME TABLE VARNAME VAL VARNAME VAL ENDTABLE ->
# tablename(varname=val, varname=val)
#
# default MSDP functions
@ -232,82 +239,4 @@ class Msdp(object):
Send oob data to Evennia
"""
#print "msdp data_in:", funcname, args, kwargs
self.protocol.data_in(text=None, oob=(funcname, args, kwargs))
# # MSDP Commands
# # Some given MSDP (varname, value) pairs can also be treated as command + argument.
# # Generic msdp command map. The argument will be sent to the given command.
# # See http://tintin.sourceforge.net/msdp/ for definitions of each command.
# # These are client->server commands.
# def msdp_cmd_list(self, arg):
# """
# The List command allows for retrieving various info about the server/client
# """
# if arg == 'COMMANDS':
# return self.evennia_to_msdp(arg, MSDP_COMMANDS)
# elif arg == 'LISTS':
# return self.evennia_to_msdp(arg, ("COMMANDS", "LISTS", "CONFIGURABLE_VARIABLES",
# "REPORTED_VARIABLES", "SENDABLE_VARIABLES"))
# elif arg == 'CONFIGURABLE_VARIABLES':
# return self.evennia_to_msdp(arg, ("CLIENT_NAME", "CLIENT_VERSION", "PLUGIN_ID"))
# elif arg == 'REPORTABLE_VARIABLES':
# return self.evennia_to_msdp(arg, MSDP_REPORTABLE.keys())
# elif arg == 'REPORTED_VARIABLES':
# # the dynamically set items to report
# return self.evennia_to_msdp(arg, self.msdp_reported.keys())
# elif arg == 'SENDABLE_VARIABLES':
# return self.evennia_to_msdp(arg, MSDP_SENDABLE.keys())
# else:
# return self.evennia_to_msdp("LIST", arg)
# # default msdp commands
# def msdp_cmd_report(self, *arg):
# """
# The report command instructs the server to start reporting a
# reportable variable to the client.
# """
# try:
# return MSDP_REPORTABLE[arg](report=True)
# except Exception:
# logger.log_trace()
# def msdp_cmd_unreport(self, arg):
# """
# Unreport a previously reported variable
# """
# try:
# MSDP_REPORTABLE[arg](report=False)
# except Exception:
# self.logger.log_trace()
# def msdp_cmd_reset(self, arg):
# """
# The reset command resets a variable to its initial state.
# """
# try:
# MSDP_REPORTABLE[arg](reset=True)
# except Exception:
# logger.log_trace()
# def msdp_cmd_send(self, *args):
# """
# Request the server to send a particular variable
# to the client.
# arg - this is a list of variables the client wants.
# """
# ret = []
# for var in make_iter(arg)
# for var in make_iter(arg):
# try:
# ret.append(MSDP_REPORTABLE[var.upper()])# (send=True))
# except Exception:
# ret.append("ERROR")#logger.log_trace()
# return ret
self.protocol.data_in(text=None, oob=(funcname, args, kwargs))

View file

@ -83,7 +83,7 @@ class Portal(object):
# create a store of services
self.services = service.IServiceCollection(application)
self.amp_protocol = None # set by amp factory
self.amp_protocol = None # set by amp factory
self.sessions = PORTAL_SESSIONS
self.sessions.portal = self
@ -99,7 +99,7 @@ class Portal(object):
be restarted or is shutting down. Valid modes are True/False and None.
If mode is None, no change will be done to the flag file.
"""
if mode == None:
if mode is None:
return
f = open(PORTAL_RESTART, 'w')
print "writing mode=%(mode)s to %(portal_restart)s" % {'mode': mode, 'portal_restart': PORTAL_RESTART}
@ -211,17 +211,20 @@ if SSL_ENABLED:
factory = protocol.ServerFactory()
factory.sessionhandler = PORTAL_SESSIONS
factory.protocol = ssl.SSLProtocol
ssl_service = internet.SSLServer(port, factory, ssl.getSSLContext(), interface=interface)
ssl_service = internet.SSLServer(port,
factory,
ssl.getSSLContext(),
interface=interface)
ssl_service.setName('EvenniaSSL%s' % pstring)
PORTAL.services.addService(ssl_service)
print " ssl%s: %s" % (ifacestr, port)
if SSH_ENABLED:
# Start SSH game connections. Will create a keypair in evennia/game if necessary.
# Start SSH game connections. Will create a keypair in
# evennia/game if necessary.
from src.server.portal import ssh
@ -234,9 +237,9 @@ if SSH_ENABLED:
ifacestr = "-%s" % interface
for port in SSH_PORTS:
pstring = "%s:%s" % (ifacestr, port)
factory = ssh.makeFactory({'protocolFactory':ssh.SshProtocol,
'protocolArgs':(),
'sessions':PORTAL_SESSIONS})
factory = ssh.makeFactory({'protocolFactory': ssh.SshProtocol,
'protocolArgs': (),
'sessions': PORTAL_SESSIONS})
ssh_service = internet.TCPServer(port, factory, interface=interface)
ssh_service.setName('EvenniaSSH%s' % pstring)
PORTAL.services.addService(ssh_service)
@ -247,8 +250,6 @@ if WEBSERVER_ENABLED:
# Start a reverse proxy to relay data to the Server-side webserver
from twisted.web import proxy
for interface in WEBSERVER_INTERFACES:
if ":" in interface:
print " iPv6 interfaces not yet supported"
@ -269,7 +270,9 @@ if WEBSERVER_ENABLED:
webclientstr = "/client"
web_root = server.Site(web_root, logPath=settings.HTTP_LOG_FILE)
proxy_service = internet.TCPServer(proxyport, web_root, interface=interface)
proxy_service = internet.TCPServer(proxyport,
web_root,
interface=interface)
proxy_service.setName('EvenniaWebProxy%s' % pstring)
PORTAL.services.addService(proxy_service)
print " webproxy%s%s:%s (<-> %s)" % (webclientstr, ifacestr, proxyport, serverport)
@ -278,7 +281,7 @@ for plugin_module in PORTAL_SERVICES_PLUGIN_MODULES:
# external plugin services to start
plugin_module.start_plugin_services(PORTAL)
print '-' * 50 # end of terminal output
print '-' * 50 # end of terminal output
if os.name == 'nt':
# Windows only: Set PID file manually

View file

@ -4,6 +4,7 @@ Sessionhandler for portal sessions
import time
from src.server.sessionhandler import SessionHandler, PCONN, PDISCONN
#------------------------------------------------------------
# Portal-SessionHandler class
#------------------------------------------------------------
@ -39,8 +40,8 @@ class PortalSessionHandler(SessionHandler):
def connect(self, session):
"""
Called by protocol at first connect. This adds a not-yet authenticated session
using an ever-increasing counter for sessid.
Called by protocol at first connect. This adds a not-yet
authenticated session using an ever-increasing counter for sessid.
"""
self.latest_sessid += 1
sessid = self.latest_sessid
@ -48,13 +49,15 @@ class PortalSessionHandler(SessionHandler):
sessdata = session.get_sync_data()
self.sessions[sessid] = session
# sync with server-side
if self.portal.amp_protocol: # this is a timing issue
if self.portal.amp_protocol: # this is a timing issue
self.portal.amp_protocol.call_remote_ServerAdmin(sessid,
operation=PCONN,
data=sessdata)
def disconnect(self, session):
"""
Called from portal side when the connection is closed from the portal side.
Called from portal side when the connection is closed
from the portal side.
"""
sessid = session.sessid
if sessid in self.sessions:
@ -86,18 +89,22 @@ class PortalSessionHandler(SessionHandler):
self.sessions = {}
def server_logged_in(self, sessid, data):
"The server tells us that the session has been authenticated. Updated it."
"""
The server tells us that the session has been
authenticated. Updated it.
"""
sess = self.get_session(sessid)
sess.load_sync_data(data)
def server_session_sync(self, serversessions):
"""
Server wants to save data to the portal, maybe because it's about to shut down.
We don't overwrite any sessions here, just update them in-place and remove
any that are out of sync (which should normally not be the case)
Server wants to save data to the portal, maybe because it's about
to shut down. We don't overwrite any sessions here, just update
them in-place and remove any that are out of sync (which should
normally not be the case)
serversessions - dictionary {sessid:{property:value},...} describing the properties
to sync on all sessions
serversessions - dictionary {sessid:{property:value},...} describing
the properties to sync on all sessions
"""
to_save = [sessid for sessid in serversessions if sessid in self.sessions]
to_delete = [sessid for sessid in self.sessions if sessid not in to_save]
@ -131,6 +138,7 @@ class PortalSessionHandler(SessionHandler):
self.portal.amp_protocol.call_remote_MsgPortal2Server(session.sessid,
msg=text,
data=kwargs)
def announce_all(self, message):
"""
Send message to all connection sessions
@ -138,7 +146,6 @@ class PortalSessionHandler(SessionHandler):
for session in self.sessions.values():
session.data_out(message)
def data_out(self, sessid, text=None, **kwargs):
"""
Called by server for having the portal relay messages and data

View file

@ -26,7 +26,7 @@ from twisted.python import components
from django.conf import settings
from src.server import session
from src.players.models import PlayerDB
from src.utils import ansi, utils, logger
from src.utils import ansi, utils
ENCODINGS = settings.ENCODINGS
@ -35,6 +35,7 @@ CTRL_D = '\x04'
CTRL_BACKSLASH = '\x1c'
CTRL_L = '\x0c'
class SshProtocol(Manhole, session.Session):
"""
Each player connecting over ssh gets this protocol assigned to
@ -47,7 +48,8 @@ class SshProtocol(Manhole, session.Session):
login automatically.
"""
self.authenticated_player = starttuple[0]
self.cfactory = starttuple[1] # obs may not be called self.factory, it gets overwritten!
# obs must not be called self.factory, that gets overwritten!
self.cfactory = starttuple[1]
def terminalSize(self, width, height):
"""
@ -95,7 +97,6 @@ class SshProtocol(Manhole, session.Session):
self.terminal.write("KeyboardInterrupt")
self.terminal.nextLine()
def handle_EOF(self):
"""
Handles EOF generally used to exit.
@ -105,7 +106,6 @@ class SshProtocol(Manhole, session.Session):
else:
self.handle_QUIT()
def handle_FF(self):
"""
Handle a 'form feed' byte - generally used to request a screen
@ -114,14 +114,12 @@ class SshProtocol(Manhole, session.Session):
self.terminal.eraseDisplay()
self.terminal.cursorHome()
def handle_QUIT(self):
"""
Quit, end, and lose the connection.
"""
self.terminal.loseConnection()
def connectionLost(self, reason=None):
"""
This is executed when the connection is lost for
@ -140,9 +138,7 @@ class SshProtocol(Manhole, session.Session):
"""
return self.terminal.transport.getPeer()
def lineReceived(self, string):
"""
Communication Player -> Evennia. Any line return indicates a
command for the purpose of the MUD. So we take the user input
@ -159,10 +155,10 @@ class SshProtocol(Manhole, session.Session):
"""
for line in string.split('\n'):
self.terminal.write(line) #this is the telnet-specific method for sending
#this is the telnet-specific method for sending
self.terminal.write(line)
self.terminal.nextLine()
# session-general method hooks
def disconnect(self, reason="Connection closed. Goodbye for now."):
@ -175,7 +171,8 @@ class SshProtocol(Manhole, session.Session):
def data_out(self, text=None, **kwargs):
"""
Data Evennia -> Player access hook. 'data' argument is a dict parsed for string settings.
Data Evennia -> Player access hook. 'data' argument is a dict
parsed for string settings.
ssh flags:
raw=True - leave all ansi markup and tokens unparsed
@ -190,9 +187,9 @@ class SshProtocol(Manhole, session.Session):
raw = kwargs.get("raw", False)
nomarkup = kwargs.get("nomarkup", False)
if raw:
self.lineSend(string)
self.lineSend(text)
else:
self.lineSend(ansi.parse_ansi(string.strip("{r") + "{r", strip_ansi=nomarkup))
self.lineSend(ansi.parse_ansi(text.strip("{r") + "{r", strip_ansi=nomarkup))
class ExtraInfoAuthServer(SSHUserAuthServer):
@ -209,6 +206,7 @@ class ExtraInfoAuthServer(SSHUserAuthServer):
return self.portal.login(c, None, IConchUser).addErrback(
self._ebPassword)
class PlayerDBPasswordChecker(object):
"""
Checks the django db for the correct credentials for
@ -232,6 +230,7 @@ class PlayerDBPasswordChecker(object):
res = (player, self.factory)
return defer.succeed(res)
class PassAvatarIdTerminalRealm(TerminalRealm):
"""
Returns an avatar that passes the avatarId through to the
@ -244,7 +243,7 @@ class PassAvatarIdTerminalRealm(TerminalRealm):
sess = self.sessionFactory(comp)
sess.transportFactory = self.transportFactory
sess.chainedProtocolFactory = lambda : self.chainedProtocolFactory(avatarId)
sess.chainedProtocolFactory = lambda: self.chainedProtocolFactory(avatarId)
comp.setComponent(iconch.IConchUser, user)
comp.setComponent(iconch.ISession, sess)
@ -252,7 +251,6 @@ class PassAvatarIdTerminalRealm(TerminalRealm):
return user
class TerminalSessionTransport_getPeer:
"""
Taken from twisted's TerminalSessionTransport which doesn't
@ -345,4 +343,4 @@ def makeFactory(configdict):
factory.portal.registerChecker(PlayerDBPasswordChecker(factory))
return factory
return factory

View file

@ -3,7 +3,8 @@ This is a simple context factory for auto-creating
SSL keys and certificates.
"""
import os, sys
import os
import sys
from twisted.internet import ssl as twisted_ssl
try:
import OpenSSL
@ -13,6 +14,7 @@ except ImportError:
from src.server.portal.telnet import TelnetProtocol
class SSLProtocol(TelnetProtocol):
"""
Communication is the same as telnet, except data transfer
@ -20,6 +22,7 @@ class SSLProtocol(TelnetProtocol):
"""
pass
def verify_SSL_key_and_cert(keyfile, certfile):
"""
This function looks for RSA key and certificate in the current
@ -41,24 +44,27 @@ def verify_SSL_key_and_cert(keyfile, certfile):
rsaKey = Key(RSA.generate(KEY_LENGTH))
keyString = rsaKey.toString(type="OPENSSH")
file(keyfile, 'w+b').write(keyString)
except Exception,e:
except Exception, e:
print "rsaKey error: %(e)s\n WARNING: Evennia could not auto-generate SSL private key." % {'e': e}
print "If this error persists, create game/%(keyfile)s yourself using third-party tools." % {'keyfile': keyfile}
sys.exit(5)
# try to create the certificate
CERT_EXPIRE = 365 * 20 # twenty years validity
CERT_EXPIRE = 365 * 20 # twenty years validity
# default:
#openssl req -new -x509 -key ssl.key -out ssl.cert -days 7300
exestring = "openssl req -new -x509 -key %s -out %s -days %s" % (keyfile, certfile, CERT_EXPIRE)
#print "exestring:", exestring
try:
err = subprocess.call(exestring)#, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
#, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
subprocess.call(exestring)
except OSError, e:
string = "\n".join([
" %s\n" % e,
" Evennia's SSL context factory could not automatically create an SSL certificate game/%(cert)s." % {'cert': certfile},
" A private key 'ssl.key' was already created. Please create %(cert)s manually using the commands valid" % {'cert': certfile},
" Evennia's SSL context factory could not automatically",
" create an SSL certificate game/%(cert)s." % {'cert': certfile},
" A private key 'ssl.key' was already created. Please",
" create %(cert)s manually using the commands valid" % {'cert': certfile},
" for your operating system.",
" Example (linux, using the openssl program): ",
" %s" % exestring])
@ -66,6 +72,7 @@ def verify_SSL_key_and_cert(keyfile, certfile):
sys.exit(5)
print "done."
def getSSLContext():
"""
Returns an SSL context (key and certificate). This function

View file

@ -9,15 +9,14 @@ sessions etc.
import re
from twisted.conch.telnet import Telnet, StatefulTelnetProtocol, IAC, LINEMODE
from twisted.internet.defer import inlineCallbacks, returnValue
from src.server.session import Session
from src.server.portal import ttype, mssp, msdp
from src.server.portal.mccp import Mccp, mccp_compress, MCCP
from src.utils import utils, ansi, logger
from src.utils.utils import make_iter, is_iter
_RE_N = re.compile(r"\{n$")
class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
"""
Each player connecting over telnet (ie using most traditional mud
@ -127,7 +126,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
def _write(self, data):
"hook overloading the one used in plain telnet"
#print "_write (%s): %s" % (self.state, " ".join(str(ord(c)) for c in data))
# print "_write (%s): %s" % (self.state, " ".join(str(ord(c)) for c in data))
data = data.replace('\n', '\r\n').replace('\r\r\n', '\r\n')
#data = data.replace('\n', '\r\n')
super(TelnetProtocol, self)._write(mccp_compress(self, data))
@ -147,7 +146,6 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
"""
self.data_in(text=string)
# Session hooks
def disconnect(self, reason=None):
@ -172,11 +170,13 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
through the telnet connection.
valid telnet kwargs:
raw=True - pass string through without any ansi processing (i.e. include Evennia
ansi markers but do not convert them into ansi tokens)
raw=True - pass string through without any ansi
processing (i.e. include Evennia ansi markers but do
not convert them into ansi tokens)
nomarkup=True - strip all ansi markup
The telnet ttype negotiation flags, if any, are used if no kwargs are given.
The telnet ttype negotiation flags, if any, are used if no kwargs
are given.
"""
try:
text = utils.to_str(text if text else "", encoding=self.encoding)
@ -200,6 +200,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
# no processing whatsoever
self.sendLine(text)
else:
# we need to make sure to kill the color at the end in order to match the webclient output.
#print "telnet data out:", self.protocol_flags, id(self.protocol_flags), id(self)
# we need to make sure to kill the color at the end in order
# to match the webclient output.
# print "telnet data out:", self.protocol_flags, id(self.protocol_flags), id(self)
self.sendLine(ansi.parse_ansi(_RE_N.sub("", text) + "{n", strip_ansi=nomarkup, xterm256=ttype.get('256 COLORS')))

View file

@ -12,12 +12,12 @@ under the 'TTYPE' key.
"""
# telnet option codes
TTYPE = chr(24)
TTYPE = chr(24)
IS = chr(0)
SEND = chr(1)
# terminal capabilities and their codes
MTTS = [(128,'PROXY'),
MTTS = [(128, 'PROXY'),
(64, 'SCREEN READER'),
(32, 'OSC COLOR PALETTE'),
(16, 'MOUSE TRACKING'),
@ -27,8 +27,8 @@ MTTS = [(128,'PROXY'),
(1, 'ANSI')]
# some clients sends erroneous strings instead
# of capability numbers. We try to convert back.
MTTS_invert = {"PROXY":128,
"SCREEN COLOR PALETTE":64,
MTTS_invert = {"PROXY": 128,
"SCREEN COLOR PALETTE": 64,
"OSC COLOR PALETTE": 32,
"MOUSE TRACKING": 16,
"256 COLORS": 8,
@ -36,6 +36,7 @@ MTTS_invert = {"PROXY":128,
"VT100": 2,
"ANSI": 1}
class Ttype(object):
"""
Handles ttype negotiations. Called and initiated by the
@ -51,7 +52,7 @@ class Ttype(object):
"""
self.ttype_step = 0
self.protocol = protocol
self.protocol.protocol_flags['TTYPE'] = {"init_done":False}
self.protocol.protocol_flags['TTYPE'] = {"init_done": False}
# setup protocol to handle ttype initialization and negotiation
self.protocol.negotiationMap[TTYPE] = self.do_ttype
# ask if client will ttype, connect callback if it does.
@ -61,7 +62,7 @@ class Ttype(object):
"""
Callback if ttype is not supported by client.
"""
self.protocol.protocol_flags['TTYPE'] = {"init_done":True}
self.protocol.protocol_flags['TTYPE'] = {"init_done": True}
def do_ttype(self, option):
"""
@ -95,9 +96,9 @@ class Ttype(object):
try:
option = int(option.strip('MTTS '))
except ValueError:
# it seems some clients don't send MTTS according to protocol
# specification, but instead just sends the data as plain
# strings. We try to convert back.
# it seems some clients don't send MTTS according to
# protocol specification, but instead just sends
# the data as plain strings. We try to convert back.
option = MTTS_invert.get(option.strip('MTTS ').upper())
if not option:
# no conversion possible. Give up.

View file

@ -20,19 +20,19 @@ import time
from hashlib import md5
from twisted.web import server, resource
from twisted.internet import defer, reactor
from django.utils import simplejson
from django.utils.functional import Promise
from django.utils.encoding import force_unicode
from django.conf import settings
from src.utils import utils, logger, ansi
from src.utils import utils, logger
from src.utils.text2html import parse_html
from src.server import session
SERVERNAME = settings.SERVERNAME
ENCODINGS = settings.ENCODINGS
# defining a simple json encoder for returning
# django data to the client. Might need to
# extend this if one wants to send more
@ -43,6 +43,8 @@ class LazyEncoder(simplejson.JSONEncoder):
if isinstance(obj, Promise):
return force_unicode(obj)
return super(LazyEncoder, self).default(obj)
def jsonify(obj):
return utils.to_str(simplejson.dumps(obj, ensure_ascii=False, cls=LazyEncoder))
@ -84,23 +86,23 @@ class WebClient(resource.Resource):
request = self.requests.get(suid)
if request:
# we have a request waiting. Return immediately.
request.write(jsonify({'msg':string, 'data':data}))
request.write(jsonify({'msg': string, 'data': data}))
request.finish()
del self.requests[suid]
else:
# no waiting request. Store data in buffer
dataentries = self.databuffer.get(suid, [])
dataentries.append(jsonify({'msg':string, 'data':data}))
dataentries.append(jsonify({'msg': string, 'data': data}))
self.databuffer[suid] = dataentries
def client_disconnect(self, suid):
"""
Disconnect session with given suid.
"""
if self.requests.has_key(suid):
if suid in self.requests:
self.requests[suid].finish()
del self.requests[suid]
if self.databuffer.has_key(suid):
if suid in self.databuffer:
del self.databuffer[suid]
def mode_init(self, request):
@ -108,7 +110,8 @@ class WebClient(resource.Resource):
This is called by render_POST when the client
requests an init mode operation (at startup)
"""
#csess = request.getSession() # obs, this is a cookie, not an evennia session!
#csess = request.getSession() # obs, this is a cookie, not
# an evennia session!
#csees.expireCallbacks.append(lambda : )
suid = request.args.get('suid', ['0'])[0]
@ -124,7 +127,7 @@ class WebClient(resource.Resource):
sess.init_session("webclient", remote_addr, self.sessionhandler)
sess.suid = suid
sess.sessionhandler.connect(sess)
return jsonify({'msg':host_string, 'suid':suid})
return jsonify({'msg': host_string, 'suid': suid})
def mode_input(self, request):
"""
@ -158,8 +161,8 @@ class WebClient(resource.Resource):
if dataentries:
return dataentries.pop(0)
request.notifyFinish().addErrback(self._responseFailed, suid, request)
if self.requests.has_key(suid):
self.requests[suid].finish() # Clear any stale request.
if suid in self.requests:
self.requests[suid].finish() # Clear any stale request.
self.requests[suid] = request
return server.NOT_DONE_YET
@ -206,6 +209,7 @@ class WebClient(resource.Resource):
# this should not happen if client sends valid data.
return ''
#
# A session type handling communication over the
# web client interface.
@ -241,7 +245,8 @@ class WebClientSession(session.Session):
if raw:
self.client.lineSend(self.suid, text)
else:
self.client.lineSend(self.suid, parse_html(text, strip_ansi=nomarkup))
self.client.lineSend(self.suid,
parse_html(text, strip_ansi=nomarkup))
return
except Exception:
logger.log_trace()