Resolve django 1.11 migration errors.
This commit is contained in:
commit
0ff1718437
54 changed files with 6444 additions and 574 deletions
|
|
@ -64,8 +64,8 @@ ENFORCED_SETTING = False
|
|||
# requirements
|
||||
PYTHON_MIN = '2.7'
|
||||
TWISTED_MIN = '16.0.0'
|
||||
DJANGO_MIN = '1.8'
|
||||
DJANGO_REC = '1.9'
|
||||
DJANGO_MIN = '1.11'
|
||||
DJANGO_REC = '1.11'
|
||||
|
||||
sys.path[1] = EVENNIA_ROOT
|
||||
|
||||
|
|
@ -344,10 +344,13 @@ ERROR_DJANGO_MIN = \
|
|||
ERROR: Django {dversion} found. Evennia requires version {django_min}
|
||||
or higher.
|
||||
|
||||
Install it with for example `pip install --upgrade django`
|
||||
If you are using a virtualenv, use the command `pip install --upgrade -e evennia` where
|
||||
`evennia` is the folder to where you cloned the Evennia library. If not
|
||||
in a virtualenv you can install django with for example `pip install --upgrade django`
|
||||
or with `pip install django=={django_min}` to get a specific version.
|
||||
|
||||
It's also a good idea to run `evennia migrate` after this upgrade.
|
||||
It's also a good idea to run `evennia migrate` after this upgrade. Ignore
|
||||
any warnings and don't run `makemigrate` even if told to.
|
||||
"""
|
||||
|
||||
NOTE_DJANGO_MIN = \
|
||||
|
|
@ -506,7 +509,7 @@ def create_secret_key():
|
|||
return secret_key
|
||||
|
||||
|
||||
def create_settings_file(init=True):
|
||||
def create_settings_file(init=True, secret_settings=False):
|
||||
"""
|
||||
Uses the template settings file to build a working settings file.
|
||||
|
||||
|
|
@ -514,18 +517,27 @@ def create_settings_file(init=True):
|
|||
init (bool): This is part of the normal evennia --init
|
||||
operation. If false, this function will copy a fresh
|
||||
template file in (asking if it already exists).
|
||||
secret_settings (bool, optional): If False, create settings.py, otherwise
|
||||
create the secret_settings.py file.
|
||||
|
||||
"""
|
||||
settings_path = os.path.join(GAMEDIR, "server", "conf", "settings.py")
|
||||
if secret_settings:
|
||||
settings_path = os.path.join(GAMEDIR, "server", "conf", "secret_settings.py")
|
||||
setting_dict = {"secret_key": "\'%s\'" % create_secret_key()}
|
||||
else:
|
||||
settings_path = os.path.join(GAMEDIR, "server", "conf", "settings.py")
|
||||
setting_dict = {
|
||||
"settings_default": os.path.join(EVENNIA_LIB, "settings_default.py"),
|
||||
"servername": "\"%s\"" % GAMEDIR.rsplit(os.path.sep, 1)[1].capitalize(),
|
||||
"secret_key": "\'%s\'" % create_secret_key()}
|
||||
|
||||
if not init:
|
||||
# if not --init mode, settings file may already exist from before
|
||||
if os.path.exists(settings_path):
|
||||
inp = input("server/conf/settings.py already exists. "
|
||||
"Do you want to reset it? y/[N]> ")
|
||||
inp = input("%s already exists. Do you want to reset it? y/[N]> " % settings_path)
|
||||
if not inp.lower() == 'y':
|
||||
print ("Aborted.")
|
||||
sys.exit()
|
||||
return
|
||||
else:
|
||||
print ("Reset the settings file.")
|
||||
|
||||
|
|
@ -535,12 +547,6 @@ def create_settings_file(init=True):
|
|||
with open(settings_path, 'r') as f:
|
||||
settings_string = f.read()
|
||||
|
||||
# tweak the settings
|
||||
setting_dict = {
|
||||
"settings_default": os.path.join(EVENNIA_LIB, "settings_default.py"),
|
||||
"servername": "\"%s\"" % GAMEDIR.rsplit(os.path.sep, 1)[1].capitalize(),
|
||||
"secret_key": "\'%s\'" % create_secret_key()}
|
||||
|
||||
settings_string = settings_string.format(**setting_dict)
|
||||
|
||||
with open(settings_path, 'w') as f:
|
||||
|
|
@ -564,8 +570,13 @@ def create_game_directory(dirname):
|
|||
sys.exit()
|
||||
# copy template directory
|
||||
shutil.copytree(EVENNIA_TEMPLATE, GAMEDIR)
|
||||
# rename gitignore to .gitignore
|
||||
os.rename(os.path.join(GAMEDIR, 'gitignore'),
|
||||
os.path.join(GAMEDIR, '.gitignore'))
|
||||
|
||||
# pre-build settings file in the new GAMEDIR
|
||||
create_settings_file()
|
||||
create_settings_file(secret_settings=True)
|
||||
|
||||
|
||||
def create_superuser():
|
||||
|
|
|
|||
|
|
@ -193,7 +193,8 @@ def client_options(session, *args, **kwargs):
|
|||
"UTF-8", "SCREENREADER", "ENCODING",
|
||||
"MCCP", "SCREENHEIGHT",
|
||||
"SCREENWIDTH", "INPUTDEBUG",
|
||||
"RAW", "NOCOLOR"))
|
||||
"RAW", "NOCOLOR",
|
||||
"NOGOAHEAD"))
|
||||
session.msg(client_options=options)
|
||||
return
|
||||
|
||||
|
|
@ -244,6 +245,8 @@ def client_options(session, *args, **kwargs):
|
|||
flags["NOCOLOR"] = validate_bool(value)
|
||||
elif key == "raw":
|
||||
flags["RAW"] = validate_bool(value)
|
||||
elif key == "nogoahead":
|
||||
flags["NOGOAHEAD"] = validate_bool(value)
|
||||
elif key in ('Char 1', 'Char.Skills 1', 'Char.Items 1',
|
||||
'Room 1', 'IRE.Rift 1', 'IRE.Composer 1'):
|
||||
# ignore mudlet's default send (aimed at IRE games)
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ class IRCBot(irc.IRCClient, Session):
|
|||
reason (str): Motivation for the disconnect.
|
||||
|
||||
"""
|
||||
self.sessionhandler.disconnect(self, reason=reason)
|
||||
self.sessionhandler.disconnect(self)
|
||||
self.stopping = True
|
||||
self.transport.loseConnection()
|
||||
|
||||
|
|
|
|||
|
|
@ -294,6 +294,7 @@ if SSH_ENABLED:
|
|||
|
||||
|
||||
if WEBSERVER_ENABLED:
|
||||
from evennia.server.webserver import Website
|
||||
|
||||
# Start a reverse proxy to relay data to the Server-side webserver
|
||||
|
||||
|
|
@ -337,7 +338,7 @@ if WEBSERVER_ENABLED:
|
|||
websocket_started = True
|
||||
webclientstr = "\n + webclient%s" % pstring
|
||||
|
||||
web_root = server.Site(web_root, logPath=settings.HTTP_LOG_FILE)
|
||||
web_root = Website(web_root, logPath=settings.HTTP_LOG_FILE)
|
||||
proxy_service = internet.TCPServer(proxyport,
|
||||
web_root,
|
||||
interface=interface)
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ class SshProtocol(Manhole, session.Session):
|
|||
else:
|
||||
# we need to make sure to kill the color at the end in order
|
||||
# to match the webclient output.
|
||||
linetosend = ansi.parse_ansi(_RE_N.sub("", text) + ("|n" if text[-1] != "|" else "||n"),
|
||||
linetosend = ansi.parse_ansi(_RE_N.sub("", text) + ("||n" if text.endswith("|") else "|n"),
|
||||
strip_ansi=nocolor, xterm256=xterm256, mxp=False)
|
||||
self.sendLine(linetosend)
|
||||
|
||||
|
|
|
|||
65
evennia/server/portal/suppress_ga.py
Normal file
65
evennia/server/portal/suppress_ga.py
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
"""
|
||||
|
||||
SUPPRESS-GO-AHEAD
|
||||
|
||||
This supports suppressing or activating Evennia
|
||||
the GO-AHEAD telnet operation after every server reply.
|
||||
If the client sends no explicit DONT SUPRESS GO-AHEAD,
|
||||
Evennia will default to supressing it since many clients
|
||||
will fail to use it and has no knowledge of this standard.
|
||||
|
||||
It is set as the NOGOAHEAD protocol_flag option.
|
||||
|
||||
http://www.faqs.org/rfcs/rfc858.html
|
||||
|
||||
"""
|
||||
from builtins import object
|
||||
SUPPRESS_GA = chr(3)
|
||||
|
||||
# default taken from telnet specification
|
||||
|
||||
# try to get the customized mssp info, if it exists.
|
||||
|
||||
class SuppressGA(object):
|
||||
"""
|
||||
Implements the SUPRESS-GO-AHEAD protocol. Add this to a variable on the telnet
|
||||
protocol to set it up.
|
||||
|
||||
"""
|
||||
def __init__(self, protocol):
|
||||
"""
|
||||
Initialize suppression of GO-AHEADs.
|
||||
|
||||
Args:
|
||||
protocol (Protocol): The active protocol instance.
|
||||
|
||||
"""
|
||||
self.protocol = protocol
|
||||
|
||||
self.protocol.protocol_flags["NOGOAHEAD"] = True
|
||||
# tell the client that we prefer to suppress GA ...
|
||||
self.protocol.will(SUPPRESS_GA).addCallbacks(self.do_suppress_ga, self.dont_suppress_ga)
|
||||
# ... but also accept if the client really wants not to.
|
||||
self.protocol.do(SUPPRESS_GA).addCallbacks(self.do_suppress_ga, self.dont_suppress_ga)
|
||||
|
||||
def dont_suppress_ga(self, option):
|
||||
"""
|
||||
Called when client requests to not suppress GA.
|
||||
|
||||
Args:
|
||||
option (Option): Not used.
|
||||
|
||||
"""
|
||||
self.protocol.protocol_flags["NOGOAHEAD"] = False
|
||||
self.protocol.handshake_done()
|
||||
|
||||
def do_suppress_ga(self, option):
|
||||
"""
|
||||
Client wants to suppress GA
|
||||
|
||||
Args:
|
||||
option (Option): Not used.
|
||||
|
||||
"""
|
||||
self.protocol.protocol_flags["NOGOAHEAD"] = True
|
||||
self.protocol.handshake_done()
|
||||
|
|
@ -13,7 +13,7 @@ from twisted.conch.telnet import Telnet, StatefulTelnetProtocol
|
|||
from twisted.conch.telnet import IAC, NOP, LINEMODE, GA, WILL, WONT, ECHO, NULL
|
||||
from django.conf import settings
|
||||
from evennia.server.session import Session
|
||||
from evennia.server.portal import ttype, mssp, telnet_oob, naws
|
||||
from evennia.server.portal import ttype, mssp, telnet_oob, naws, suppress_ga
|
||||
from evennia.server.portal.mccp import Mccp, mccp_compress, MCCP
|
||||
from evennia.server.portal.mxp import Mxp, mxp_parse
|
||||
from evennia.utils import ansi
|
||||
|
|
@ -47,9 +47,11 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
|
|||
client_address = client_address[0] if client_address else None
|
||||
# this number is counted down for every handshake that completes.
|
||||
# when it reaches 0 the portal/server syncs their data
|
||||
self.handshakes = 7 # naws, ttype, mccp, mssp, msdp, gmcp, mxp
|
||||
self.handshakes = 8 # suppress-go-ahead, naws, ttype, mccp, mssp, msdp, gmcp, mxp
|
||||
self.init_session(self.protocol_name, client_address, self.factory.sessionhandler)
|
||||
|
||||
# suppress go-ahead
|
||||
self.sga = suppress_ga.SuppressGA(self)
|
||||
# negotiate client size
|
||||
self.naws = naws.Naws(self)
|
||||
# negotiate ttype (client info)
|
||||
|
|
@ -128,7 +130,8 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
|
|||
option == ttype.TTYPE or
|
||||
option == naws.NAWS or
|
||||
option == MCCP or
|
||||
option == mssp.MSSP)
|
||||
option == mssp.MSSP or
|
||||
option == suppress_ga.SUPPRESS_GA)
|
||||
|
||||
def enableLocal(self, option):
|
||||
"""
|
||||
|
|
@ -141,7 +144,9 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
|
|||
enable (bool): If this option should be enabled.
|
||||
|
||||
"""
|
||||
return option == MCCP or option == ECHO
|
||||
return (option == MCCP or
|
||||
option == ECHO or
|
||||
option == suppress_ga.SUPPRESS_GA)
|
||||
|
||||
def disableLocal(self, option):
|
||||
"""
|
||||
|
|
@ -221,6 +226,8 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
|
|||
# escape IAC in line mode, and correctly add \r\n
|
||||
line += self.delimiter
|
||||
line = line.replace(IAC, IAC + IAC).replace('\n', '\r\n')
|
||||
if not self.protocol_flags.get("NOGOAHEAD", True):
|
||||
line += IAC + GA
|
||||
return self.transport.write(mccp_compress(self, line))
|
||||
|
||||
# Session hooks
|
||||
|
|
@ -309,7 +316,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
|
|||
prompt = text
|
||||
if not raw:
|
||||
# processing
|
||||
prompt = ansi.parse_ansi(_RE_N.sub("", prompt) + ("|n" if prompt[-1] != "|" else "||n"),
|
||||
prompt = ansi.parse_ansi(_RE_N.sub("", prompt) + ("||n" if prompt.endswith("|") else "|n"),
|
||||
strip_ansi=nocolor, xterm256=xterm256)
|
||||
if mxp:
|
||||
prompt = mxp_parse(prompt)
|
||||
|
|
@ -337,7 +344,7 @@ class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
|
|||
else:
|
||||
# we need to make sure to kill the color at the end in order
|
||||
# to match the webclient output.
|
||||
linetosend = ansi.parse_ansi(_RE_N.sub("", text) + ("|n" if text[-1] != "|" else "||n"),
|
||||
linetosend = ansi.parse_ansi(_RE_N.sub("", text) + ("||n" if text.endswith("|") else "|n"),
|
||||
strip_ansi=nocolor, xterm256=xterm256, mxp=mxp)
|
||||
if mxp:
|
||||
linetosend = mxp_parse(linetosend)
|
||||
|
|
|
|||
|
|
@ -47,7 +47,11 @@ IAC = chr(255)
|
|||
SB = chr(250)
|
||||
SE = chr(240)
|
||||
|
||||
force_str = lambda inp: to_str(inp, force_string=True)
|
||||
|
||||
def force_str(inp):
|
||||
"""Helper to shorten code"""
|
||||
return to_str(inp, force_string=True)
|
||||
|
||||
|
||||
# pre-compiled regexes
|
||||
# returns 2-tuple
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import os
|
|||
from twisted.web import static
|
||||
from twisted.application import internet, service
|
||||
from twisted.internet import reactor, defer
|
||||
from twisted.internet.task import LoopingCall
|
||||
from twisted.internet.task import LoopingCall, deferLater
|
||||
|
||||
import django
|
||||
django.setup()
|
||||
|
|
@ -151,7 +151,8 @@ class Evennia(object):
|
|||
sys.path.insert(1, '.')
|
||||
|
||||
# create a store of services
|
||||
self.services = service.IServiceCollection(application)
|
||||
self.services = service.MultiService()
|
||||
self.services.setServiceParent(application)
|
||||
self.amp_protocol = None # set by amp factory
|
||||
self.sessions = SESSIONS
|
||||
self.sessions.server = self
|
||||
|
|
@ -167,10 +168,21 @@ class Evennia(object):
|
|||
# initialize channelhandler
|
||||
channelhandler.CHANNELHANDLER.update()
|
||||
|
||||
# set a callback if the server is killed abruptly,
|
||||
# by Ctrl-C, reboot etc.
|
||||
reactor.addSystemEventTrigger('before', 'shutdown',
|
||||
self.shutdown, _reactor_stopping=True)
|
||||
# wrap the SIGINT handler to make sure we empty the threadpool
|
||||
# even when we reload and we have long-running requests in queue.
|
||||
# this is necessary over using Twisted's signal handler.
|
||||
# (see https://github.com/evennia/evennia/issues/1128)
|
||||
def _wrap_sigint_handler(*args):
|
||||
from twisted.internet.defer import Deferred
|
||||
if hasattr(self, "web_root"):
|
||||
d = self.web_root.empty_threadpool()
|
||||
d.addCallback(lambda _: self.shutdown(_reactor_stopping=True))
|
||||
else:
|
||||
d = Deferred(lambda _: self.shutdown(_reactor_stopping=True))
|
||||
d.addCallback(lambda _: reactor.stop())
|
||||
reactor.callLater(1, d.callback, None)
|
||||
reactor.sigInt = _wrap_sigint_handler
|
||||
|
||||
self.game_running = True
|
||||
|
||||
# track the server time
|
||||
|
|
@ -183,7 +195,7 @@ class Evennia(object):
|
|||
Optimize some SQLite stuff at startup since we
|
||||
can't save it to the database.
|
||||
"""
|
||||
if ((".".join(str(i) for i in django.VERSION) < "1.2" and settings.DATABASE_ENGINE == "sqlite3")
|
||||
if ((".".join(str(i) for i in django.VERSION) < "1.2" and settings.DATABASES.get('default', {}).get('ENGINE') == "sqlite3")
|
||||
or (hasattr(settings, 'DATABASES')
|
||||
and settings.DATABASES.get("default", {}).get('ENGINE', None)
|
||||
== 'django.db.backends.sqlite3')):
|
||||
|
|
@ -383,16 +395,16 @@ class Evennia(object):
|
|||
# always called, also for a reload
|
||||
self.at_server_stop()
|
||||
|
||||
# if _reactor_stopping is true, reactor does not need to
|
||||
# be stopped again.
|
||||
if os.name == 'nt' and os.path.exists(SERVER_PIDFILE):
|
||||
# for Windows we need to remove pid files manually
|
||||
os.remove(SERVER_PIDFILE)
|
||||
|
||||
if hasattr(self, "web_root"): # not set very first start
|
||||
yield self.web_root.empty_threadpool()
|
||||
|
||||
if not _reactor_stopping:
|
||||
# this will also send a reactor.stop signal, so we set a
|
||||
# flag to avoid loops.
|
||||
self.shutdown_complete = True
|
||||
# kill the server
|
||||
self.shutdown_complete = True
|
||||
reactor.callLater(1, reactor.stop)
|
||||
|
||||
# we make sure the proper gametime is saved as late as possible
|
||||
|
|
@ -526,18 +538,20 @@ if WEBSERVER_ENABLED:
|
|||
|
||||
# Start a django-compatible webserver.
|
||||
|
||||
from twisted.python import threadpool
|
||||
from evennia.server.webserver import DjangoWebRoot, WSGIWebServer, Website
|
||||
#from twisted.python import threadpool
|
||||
from evennia.server.webserver import DjangoWebRoot, WSGIWebServer, Website, LockableThreadPool
|
||||
|
||||
# start a thread pool and define the root url (/) as a wsgi resource
|
||||
# recognized by Django
|
||||
threads = threadpool.ThreadPool(minthreads=max(1, settings.WEBSERVER_THREADPOOL_LIMITS[0]),
|
||||
threads = LockableThreadPool(minthreads=max(1, settings.WEBSERVER_THREADPOOL_LIMITS[0]),
|
||||
maxthreads=max(1, settings.WEBSERVER_THREADPOOL_LIMITS[1]))
|
||||
|
||||
web_root = DjangoWebRoot(threads)
|
||||
# point our media resources to url /media
|
||||
web_root.putChild("media", static.File(settings.MEDIA_ROOT))
|
||||
# point our static resources to url /static
|
||||
web_root.putChild("static", static.File(settings.STATIC_ROOT))
|
||||
EVENNIA.web_root = web_root
|
||||
|
||||
if WEB_PLUGINS_MODULE:
|
||||
# custom overloads
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ from twisted.internet import reactor
|
|||
from twisted.application import internet
|
||||
from twisted.web.proxy import ReverseProxyResource
|
||||
from twisted.web.server import NOT_DONE_YET
|
||||
from twisted.python import threadpool
|
||||
from twisted.internet import defer
|
||||
|
||||
from twisted.web.wsgi import WSGIResource
|
||||
from django.conf import settings
|
||||
|
|
@ -28,6 +30,27 @@ from evennia.utils import logger
|
|||
_UPSTREAM_IPS = settings.UPSTREAM_IPS
|
||||
_DEBUG = settings.DEBUG
|
||||
|
||||
|
||||
class LockableThreadPool(threadpool.ThreadPool):
|
||||
"""
|
||||
Threadpool that can be locked from accepting new requests.
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
self._accept_new = True
|
||||
threadpool.ThreadPool.__init__(self, *args, **kwargs)
|
||||
|
||||
def lock(self):
|
||||
self._accept_new = False
|
||||
|
||||
def callInThread(self, func, *args, **kwargs):
|
||||
"""
|
||||
called in the main reactor thread. Makes sure the pool
|
||||
is not locked before continuing.
|
||||
"""
|
||||
if self._accept_new:
|
||||
threadpool.ThreadPool.callInThread(self, func, *args, **kwargs)
|
||||
|
||||
|
||||
#
|
||||
# X-Forwarded-For Handler
|
||||
#
|
||||
|
|
@ -102,7 +125,7 @@ class EvenniaReverseProxyResource(ReverseProxyResource):
|
|||
clientFactory.noisy = False
|
||||
self.reactor.connectTCP(self.host, self.port, clientFactory)
|
||||
# don't trigger traceback if connection is lost before request finish.
|
||||
request.notifyFinish().addErrback(lambda f: f.cancel())
|
||||
request.notifyFinish().addErrback(lambda f: logger.log_trace("%s\nCaught errback in webserver.py:75." % f))
|
||||
return NOT_DONE_YET
|
||||
|
||||
|
||||
|
|
@ -115,8 +138,9 @@ class DjangoWebRoot(resource.Resource):
|
|||
"""
|
||||
This creates a web root (/) that Django
|
||||
understands by tweaking the way
|
||||
child instancee ars recognized.
|
||||
child instances are recognized.
|
||||
"""
|
||||
|
||||
def __init__(self, pool):
|
||||
"""
|
||||
Setup the django+twisted resource.
|
||||
|
|
@ -125,9 +149,30 @@ class DjangoWebRoot(resource.Resource):
|
|||
pool (ThreadPool): The twisted threadpool.
|
||||
|
||||
"""
|
||||
self.pool = pool
|
||||
self._echo_log = True
|
||||
self._pending_requests = {}
|
||||
resource.Resource.__init__(self)
|
||||
self.wsgi_resource = WSGIResource(reactor, pool, WSGIHandler())
|
||||
|
||||
def empty_threadpool(self):
|
||||
"""
|
||||
Converts our _pending_requests list of deferreds into a DeferredList
|
||||
|
||||
Returns:
|
||||
deflist (DeferredList): Contains all deferreds of pending requests.
|
||||
|
||||
"""
|
||||
self.pool.lock()
|
||||
if self._pending_requests and self._echo_log:
|
||||
self._echo_log = False # just to avoid multiple echoes
|
||||
msg = "Webserver waiting for %i requests ... "
|
||||
logger.log_info(msg % len(self._pending_requests))
|
||||
return defer.DeferredList(self._pending_requests, consumeErrors=True)
|
||||
|
||||
def _decrement_requests(self, *args, **kwargs):
|
||||
self._pending_requests.pop(kwargs.get('deferred', None), None)
|
||||
|
||||
def getChild(self, path, request):
|
||||
"""
|
||||
To make things work we nudge the url tree to make this the
|
||||
|
|
@ -137,11 +182,22 @@ class DjangoWebRoot(resource.Resource):
|
|||
path (str): Url path.
|
||||
request (Request object): Incoming request.
|
||||
|
||||
Notes:
|
||||
We make sure to save the request queue so
|
||||
that we can safely kill the threadpool
|
||||
on a server reload.
|
||||
|
||||
"""
|
||||
path0 = request.prepath.pop(0)
|
||||
request.postpath.insert(0, path0)
|
||||
|
||||
deferred = request.notifyFinish()
|
||||
self._pending_requests[deferred] = deferred
|
||||
deferred.addBoth(self._decrement_requests, deferred=deferred)
|
||||
|
||||
return self.wsgi_resource
|
||||
|
||||
|
||||
#
|
||||
# Site with deactivateable logging
|
||||
#
|
||||
|
|
@ -151,11 +207,13 @@ class Website(server.Site):
|
|||
This class will only log http requests if settings.DEBUG is True.
|
||||
"""
|
||||
noisy = False
|
||||
|
||||
def log(self, request):
|
||||
"Conditional logging"
|
||||
"""Conditional logging"""
|
||||
if _DEBUG:
|
||||
server.Site.log(self, request)
|
||||
|
||||
|
||||
#
|
||||
# Threaded Webserver
|
||||
#
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue