Mayor first overhaul of the evennia.py launcher. Not tested yet.

This commit is contained in:
Griatch 2015-01-06 14:39:10 +01:00
parent 84483b7842
commit 2846e64833

View file

@ -8,71 +8,70 @@ Sets the appropriate environmental variables and launches the server
and portal through the runner. Run without arguments to get a and portal through the runner. Run without arguments to get a
menu. Run the script with the -h flag to see usage information. menu. Run the script with the -h flag to see usage information.
Usage:
evennia init <path> - creates a new game location, sets up a custom
settings file and copies all templates to <path>
evennia [settings][options] - handles server start/stop/restart if called
from the game folder. Can be called outside
the game folder if called with the path
to the settings file.
""" """
import os import os
import sys import sys
import signal import signal
from optparse import OptionParser import shutil
from subprocess import Popen import importlib
import django import django
from argparse import ArgumentParser
# Set the Python path up so we can get to settings.py from here. from subprocess import Popen
from django.core import management from django.core import management
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # Signal processing
SIG = signal.SIGINT
# Check/Create settings # Set up the main python paths to Evennia
EVENNIA_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
EVENNIA_BIN = os.path.join(EVENNIA_ROOT, "bin")
EVENNIA_LIB = os.path.join(EVENNIA_ROOT, "lib")
EVENNIA_RUNNER = os.path.join(EVENNIA_BIN, "runner.py")
EVENNIA_TEMPLATE = os.path.join(EVENNIA_ROOT, "game_template")
_CREATED_SETTINGS = False EVENNIA_VERSION = "Unknown"
if not os.path.exists('settings.py'): TWISTED_BINARY = "twistd"
# If settings.py doesn't already exist, create it and populate it with some
# basic stuff.
# make random secret_key. # Game directory structure
import random SETTINGFILE = "settings.py"
import string SERVERDIR = "server"
secret_key = list((string.letters + CONFDIR = os.path.join(SERVERDIR, "conf")
string.digits + string.punctuation).replace("\\", "").replace("'", '"')) SETTINGS_PATH = os.path.join(CONFDIR, SETTINGFILE)
random.shuffle(secret_key) SETTINGS_DOTPATH = "server.conf.settings"
secret_key = "".join(secret_key[:40]) CURRENT_DIR = os.getcwd()
GAMEDIR = CURRENT_DIR
settings_file = open('settings.py', 'w') # Operational setup
_CREATED_SETTINGS = True SERVER_LOGFILE = None
PORTAL_LOGFILE = None
SERVER_PIDFILE = None
PORTAL_PIDFILE = None
SERVER_RESTART = None
PORTAL_RESTART = None
SERVER_PY_FILE = None
PORTAL_PY_FILE = None
string = \ # add Evennia root and bin dir to PYTHONPATH
sys.path.insert(0, EVENNIA_ROOT)
#------------------------------------------------------------
#
# Messages
#
#------------------------------------------------------------
WELCOME_MESSAGE = \
""" """
######################################################################
# Evennia MU* server configuration file
#
# You may customize your setup by copy&pasting the variables you want
# to change from the master config file src/settings_default.py to
# this file. Try to *only* copy over things you really need to customize
# and do *not* make any changes to src/settings_default.py directly.
# This way you'll always have a sane default to fall back on
# (also, the master config file may change with server updates).
#
######################################################################
from src.settings_default import *
######################################################################
# Custom settings
######################################################################
######################################################################
# SECRET_KEY was randomly seeded when settings.py was first created.
# Don't share this with anybody. It is used by Evennia to handle
# cryptographic hashing for things like cookies on the web side.
######################################################################
SECRET_KEY = '%s'
""" % secret_key
settings_file.write(string)
settings_file.close()
print """
Welcome to Evennia! Welcome to Evennia!
No previous setting file was found so we created a fresh No previous setting file was found so we created a fresh
@ -87,81 +86,101 @@ SECRET_KEY = '%s'
Make sure to create a superuser when asked. The superuser's Make sure to create a superuser when asked. The superuser's
email-address does not have to exist. email-address does not have to exist.
""" """
sys.exit()
#------------------------------------------------------------ WARNING_RUNSERVER = \
# Test the import of the settings file """
#------------------------------------------------------------ WARNING: There is no need to run the Django development
try: webserver to test out Evennia web features (the web client
from game import settings will in fact not work since the Django test server knows
except Exception: nothing about MUDs). Instead, just start Evennia with the
import traceback webserver component active (this is the default).
string = "\n" + traceback.format_exc() """
# note - if this fails, ugettext will also fail, so we cannot translate this string. ERROR_SETTINGS = \
"""
string += """\n ERROR: Could not import the file {settingsfile} from {settingspath}.
Error: Couldn't import the file 'settings.py' in the directory containing %(file)r.
There are usually two reasons for this: There are usually two reasons for this:
1) The settings module contains errors. Review the traceback above to resolve the 1) The settings file is a normal Python module. It may contain a syntax error.
problem, then try again. Resolve the problem and try again.
2) If you get errors on finding DJANGO_SETTINGS_MODULE you might have set up django 2) Django is not correctly installed. This usually shows by errors involving
wrong in some way. If you run a virtual machine, it might be worth to restart it 'DJANGO_SETTINGS_MODULE'. If you run a virtual machine, it might be worth to restart it
to see if this resolves the issue. Evennia should not require you to define any to see if this resolves the issue.
environment variables manually. """.format(settingsfile=SETTINGFILE, settingspath=SETTINGS_PATH)
""" % {'file': __file__}
print string
sys.exit(1)
# set the settings location ERROR_DATABASE = \
os.environ['DJANGO_SETTINGS_MODULE'] = 'game.settings' """
Your database does not seem to be set up correctly.
(error was '{traceback}')
# required since django1.7. Try to run
django.setup()
# signal processing python evennia.py
SIG = signal.SIGINT
to initialize the database according to your settings.
"""
ERROR_WINDOWS_WIN32API = \
"""
ERROR: Unable to import win32api, which Twisted requires to run.
You may download it from:
http://sourceforge.net/projects/pywin32
or
http://starship.python.net/crew/mhammond/win32/Downloads.html
"""
INFO_WINDOWS_BATFILE = \
"""
INFO: Since you are running Windows, a file 'twistd.bat' was
created for you. This is a simple batch file that tries to call
the twisted executable. Evennia determined this to be:
%(twistd_path)s
If you run into errors at startup you might need to edit
twistd.bat to point to the actual location of the Twisted
executable (usually called twistd.py) on your machine.
This procedure is only done once. Run evennia.py again when you
are ready to start the server.
"""
CMDLINE_HELP = \ CMDLINE_HELP = \
""" """
Main Evennia launcher. When starting in interactive (-i) mode, only Main Evennia launcher. When starting in interactive (-i) mode, only
the Server will do so since this is the most commonly useful setup. To the Server will do so since this is the most commonly useful setup. To
activate interactive mode also for the Portal, use the menu or launch activate interactive mode also for the Portal, use the menu or launch
the two services one after the other as two separate calls to this the two services one after the other as two separate calls to this
program. program.
""" """
VERSION_INFO = \ VERSION_INFO = \
""" """
Evennia {version} Evennia {version}
{about} {about}
OS: {os} OS: {os}
Python: {python} Python: {python}
Twisted: {twisted} Twisted: {twisted}
Django: {django} Django: {django}
{south} """
"""
ABOUT_INFO= \ ABOUT_INFO= \
""" """
MUD/MUX/MU* development system Evennia MUD/MUX/MU* development system
Licence: BSD 3-Clause Licence Licence: BSD 3-Clause Licence
Web: http://www.evennia.com Web: http://www.evennia.com
Irc: #evennia on FreeNode Irc: #evennia on FreeNode
Forum: http://www.evennia.com/discussions Forum: http://www.evennia.com/discussions
Maintainer (2010-): Griatch (griatch AT gmail DOT com) Maintainer (2010-): Griatch (griatch AT gmail DOT com)
Maintainer (2006-10): Greg Taylor Maintainer (2006-10): Greg Taylor
""" """
HELP_ENTRY = \ HELP_ENTRY = \
""" """
(version %s) See python evennia.py -h for controlling Evennia directly from
the command line.
All launcher functionality can be accessed directly from the command
line. See python evennia.py -h for options.
Evennia has two parts that both must run: Evennia has two parts that both must run:
@ -212,89 +231,185 @@ MENU = \
""" """
#------------------------------------------------------------
# #
# System Configuration and setup # Functions
# #
#------------------------------------------------------------
SERVER_PIDFILE = "server.pid" def evennia_version():
PORTAL_PIDFILE = "portal.pid" """
Get the Evennia version info from the main package.
SERVER_RESTART = "server.restart" """
PORTAL_RESTART = "portal.restart" version = "Unknown"
with open(os.path.join(EVENNIA_ROOT, "VERSION.txt"), 'r') as f:
# Get the settings version = f.read().strip()
from django.conf import settings
from src.utils.utils import get_evennia_version
EVENNIA_VERSION = get_evennia_version()
# Setup access of the evennia server itself
SERVER_PY_FILE = os.path.join(settings.SRC_DIR, 'server/server.py')
PORTAL_PY_FILE = os.path.join(settings.SRC_DIR, 'server/portal.py')
# Get logfile names
SERVER_LOGFILE = settings.SERVER_LOG_FILE
PORTAL_LOGFILE = settings.PORTAL_LOG_FILE
# Add this to the environmental variable for the 'twistd' command.
currpath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if 'PYTHONPATH' in os.environ:
os.environ['PYTHONPATH'] += (":%s" % currpath)
else:
os.environ['PYTHONPATH'] = currpath
TWISTED_BINARY = 'twistd'
if os.name == 'nt':
# Windows needs more work to get the correct binary
try: try:
# Test for for win32api version = "%s(GIT %s)" % (version, os.popen("git rev-parse --short HEAD").read().strip())
import win32api except IOError:
except ImportError: pass
print """ return version
ERROR: Unable to import win32api, which Twisted requires to run.
You may download it from:
http://sourceforge.net/projects/pywin32
or def init_game_directory(path):
http://starship.python.net/crew/mhammond/win32/Downloads.html""" """
Try to analyze the given path to find settings.py - this defines
the game directory and also sets PYTHONPATH as well as the
django path.
"""
global GAMEDIR
if os.path.exists(os.path.join(path, SETTINGFILE)):
# path given to server/conf/
GAMEDIR = os.path.dirname(os.path.dirname(os.path.dirname(path)))
elif os.path.exists(SETTINGS_PATH):
# path given to somewhere else in gamedir
GAMEDIR = os.path.dirname(os.path.dirname(path))
else:
# Assume path given to root game dir
GAMEDIR = path
# set pythonpath to gamedir
sys.path.insert(0, GAMEDIR)
# set the settings location
os.environ['DJANGO_SETTINGS_MODULE'] = SETTINGS_DOTPATH
# required since django1.7.
django.setup()
# check all dependencies
from evennia.utils.utils import check_evennia_dependencies
if not check_evennia_
# test existence of settings module
try:
settings = importlib.import_module(SETTINGS_DOTPATH)
except Exception:
import traceback
print "\n" + traceback.format_exc()
print ERROR_SETTINGS
sys.exit() sys.exit()
if not os.path.exists('twistd.bat'): # set up the Evennia executables and log file locations
# Test for executable twisted batch file. This calls the twistd.py global SERVER_PY_FILE, PORTAL_PY_FILE
# executable that is usually not found on the path in Windows. global SERVER_LOGFILE, PORTAL_LOGFILE
# It's not enough to locate scripts.twistd, what we want is the global SERVER_PIDFILE, PORTAL_PIDFILE
# executable script C:\PythonXX/Scripts/twistd.py. Alas we cannot global SERVER_RESTART, PORTAL_RESTART
# hardcode this location since we don't know if user has Python global EVENNIA_VERSION
# in a non-standard location, so we try to figure it out.
from twisted.scripts import twistd
twistd_path = os.path.abspath(
os.path.join(os.path.dirname(twistd.__file__),
os.pardir, os.pardir, os.pardir, os.pardir,
'scripts', 'twistd.py'))
bat_file = open('twistd.bat', 'w')
bat_file.write("@\"%s\" \"%s\" %%*" % (sys.executable, twistd_path))
bat_file.close()
print """
INFO: Since you are running Windows, a file 'twistd.bat' was
created for you. This is a simple batch file that tries to call
the twisted executable. Evennia determined this to be:
%(twistd_path)s SERVER_PY_FILE = os.path.join(settings.LIB_DIR, "server/server.py")
PORTAL_PY_FILE = os.path.join(settings.LIB_DIR, "portal/server.py")
If you run into errors at startup you might need to edit SERVER_PIDFILE = os.path.join(GAMEDIR, SERVERDIR, "server.pid")
twistd.bat to point to the actual location of the Twisted PORTAL_PIDFILE = os.path.join(GAMEDIR, SERVERDIR, "portal.pid")
executable (usually called twistd.py) on your machine.
This procedure is only done once. Run evennia.py again when you SERVER_RESTART = os.path.join(GAMEDIR, SERVERDIR, "server.restart")
are ready to start the server. PORTAL_RESTART = os.path.join(GAMEDIR, SERVERDIR, "portal.restart")
""" % {'twistd_path': twistd_path}
sys.exit()
TWISTED_BINARY = 'twistd.bat' SERVER_LOGFILE = settings.SERVER_LOG_FILE
PORTAL_LOGFILE = settings.PORTAL_LOG_FILE
# This also tests the library access
from evennia.utils.utils import get_evennia_version
EVENNIA_VERSION = get_evennia_version()
# set up twisted
if os.name == 'nt':
# We need to handle Windows twisted separately. We create a
# batchfile in game/server, linking to the actual binary
global TWISTED_BINARY
TWISTED_BINARY = "twistd.bat"
# add path so system can find the batfile
sys.path.insert(0, os.path.join(GAMEDIR, SERVERDIR))
try:
importlib.import_module("win32api")
except ImportError:
print ERROR_WINDOWS_WIN32API
sys.exit()
if not os.path.exists(os.path.join(EVENNIA_BIN, TWISTED_BINARY)):
# Test for executable twisted batch file. This calls the
# twistd.py executable that is usually not found on the
# path in Windows. It's not enough to locate
# scripts.twistd, what we want is the executable script
# C:\PythonXX/Scripts/twistd.py. Alas we cannot hardcode
# this location since we don't know if user has Python in
# a non-standard location. So we try to figure it out.
twistd = importlib.import_module("twisted.scripts.twistd")
twistd_dir = os.path.dirname(twistd.__file__)
# note that we hope the twistd package won't change here, since we
# try to get to the executable by relative path.
twistd_path = os.path.abspath(os.path.join(twistd_dir,
os.pardir, os.pardir, os.pardir, os.pardir,
'scripts', 'twistd.py'))
with open('twistd.bat', 'w') as bat_file:
# build a custom bat file for windows
bat_file.write("@\"%s\" \"%s\" %%*" % (sys.executable, twistd_path))
print INFO_WINDOWS_BATFILE.format(twistd_path=twistd_path)
#
# Check/Create settings
#
def create_secret_key():
"""
Randomly create the secret key for the settings file
"""
import random
import string
secret_key = list((string.letters +
string.digits + string.punctuation).replace("\\", "").replace("'", '"'))
random.shuffle(secret_key)
secret_key = "".join(secret_key[:40])
return secret_key
def create_settings_file():
"""
Uses the template settings file to build a working
settings file.
"""
settings_path = os.path.join(GAMEDIR, "server", "conf", "settings.py")
with open(settings_path, 'r') as f:
settings_string = f.read()
# tweak the settings
setting_dict = {"servername":"Evennia",
"secret_key":create_secret_key}
# modify the settings
settings_string.format(**setting_dict)
with open(settings_path, 'w') as f:
f.write(settingsj_string)
# Functions # Functions
def create_game_directory(dirname):
"""
Initialize a new game directory named dirname
at the current path. This means copying the
template directory from evennia's root.
"""
global GAMEDIR
GAMEDIR = os.abspath(os.path.join(CURRENT_DIR, dirname))
if os.path.exists(GAMEDIR):
print "Cannot create new Evennia game dir: '%s' already exists." % dirname
sys.exit()
# copy template directory
shutil.copytree(EVENNIA_TEMPLATE, GAMEDIR)
# pre-build settings file in the new GAMEDIR
create_settings_file()
def get_pid(pidfile): def get_pid(pidfile):
""" """
Get the PID (Process ID) by trying to access Get the PID (Process ID) by trying to access
@ -351,25 +466,19 @@ def show_version_info(about=False):
import os, sys import os, sys
import twisted import twisted
import django import django
try:
import south
sversion = "South %s" % south.__version__
except ImportError:
sversion = "South <not installed>"
return VERSION_INFO.format(version=EVENNIA_VERSION, return VERSION_INFO.format(version=EVENNIA_VERSION,
about=ABOUT_INFO if about else "", about=ABOUT_INFO if about else "",
os=os.name, python=sys.version.split()[0], os=os.name, python=sys.version.split()[0],
twisted=twisted.version.short(), twisted=twisted.version.short(),
django=django.get_version(), django=django.get_version())
south=sversion)
def run_menu(): def run_menu():
""" """
This launches an interactive menu. This launches an interactive menu.
""" """
cmdstr = [sys.executable, "runner.py"] cmdstr = [sys.executable, EVENNIA_RUNNER]
while True: while True:
# menu loop # menu loop
@ -405,7 +514,10 @@ def run_menu():
cmdstr.extend(['--iportal']) cmdstr.extend(['--iportal'])
elif inp == 4: elif inp == 4:
cmdstr.extend(['--iserver', '--iportal']) cmdstr.extend(['--iserver', '--iportal'])
return cmdstr # start server
cmdstr.append("start")
Popen(cmdstr)
return
elif inp < 10: elif inp < 10:
if inp == 5: if inp == 5:
if os.name == 'nt': if os.name == 'nt':
@ -427,20 +539,18 @@ def run_menu():
return return
else: else:
print "Not a valid option." print "Not a valid option."
return None
def handle_args(options, mode, service): def server_operation(mode, service, interactive):
""" """
Handle argument options given on the command line. Handle argument options given on the command line.
options - parsed object for command line
mode - str; start/stop etc mode - str; start/stop etc
service - str; server, portal or all service - str; server, portal or all
interactive - bool; use interactive mode or daemon
""" """
inter = options.interactive cmdstr = [sys.executable, EVENNIA_RUNNER]
cmdstr = [sys.executable, "runner.py"]
errmsg = "The %s does not seem to be running." errmsg = "The %s does not seem to be running."
if mode == 'start': if mode == 'start':
@ -450,21 +560,23 @@ def handle_args(options, mode, service):
# starting one or many services # starting one or many services
if service == 'server': if service == 'server':
if inter: if interactive:
cmdstr.append('--iserver') cmdstr.append('--iserver')
cmdstr.append('--noportal') cmdstr.append('--noportal')
elif service == 'portal': elif service == 'portal':
if inter: if interactive:
cmdstr.append('--iportal') cmdstr.append('--iportal')
cmdstr.append('--noserver') cmdstr.append('--noserver')
management.call_command('collectstatic', verbosity=1, interactive=False) management.call_command('collectstatic', verbosity=1, interactive=False)
else: # all else: # all
# for convenience we don't start logging of # for convenience we don't start logging of
# portal, only of server with this command. # portal, only of server with this command.
if inter: if interactive:
cmdstr.extend(['--iserver']) cmdstr.extend(['--iserver'])
management.call_command('collectstatic', verbosity=1, interactive=False) management.call_command('collectstatic', verbosity=1, interactive=False)
return cmdstr # start the server
cmdstr.append("start")
Popen(cmdstr)
elif mode == 'reload': elif mode == 'reload':
# restarting services # restarting services
@ -493,7 +605,6 @@ def handle_args(options, mode, service):
else: else:
kill(PORTAL_PIDFILE, SIG, "Portal stopped.", errmsg % 'Portal', PORTAL_RESTART, restart=False) kill(PORTAL_PIDFILE, SIG, "Portal stopped.", errmsg % 'Portal', PORTAL_RESTART, restart=False)
kill(SERVER_PIDFILE, SIG, "Server stopped.", errmsg % 'Server', restart="shutdown") kill(SERVER_PIDFILE, SIG, "Server stopped.", errmsg % 'Server', restart="shutdown")
return None
def error_check_python_modules(): def error_check_python_modules():
@ -504,20 +615,16 @@ def error_check_python_modules():
the python source files themselves). Best they fail already here the python source files themselves). Best they fail already here
before we get any further. before we get any further.
""" """
def imp(path, split=True): from django.conf import settings
mod, fromlist = path, "None"
if split:
mod, fromlist = path.rsplit('.', 1)
__import__(mod, fromlist=[fromlist])
# core modules # core modules
imp(settings.COMMAND_PARSER) importlib.import_module(settings.COMMAND_PARSER)
imp(settings.SEARCH_AT_RESULT) importlib.import_module(settings.SEARCH_AT_RESULT)
imp(settings.SEARCH_AT_MULTIMATCH_INPUT) importlib.import_module(settings.SEARCH_AT_MULTIMATCH_INPUT)
imp(settings.CONNECTION_SCREEN_MODULE, split=False) importlib.import_module(settings.CONNECTION_SCREEN_MODULE, split=False)
#imp(settings.AT_INITIAL_SETUP_HOOK_MODULE, split=False) #imp(settings.AT_INITIAL_SETUP_HOOK_MODULE, split=False)
for path in settings.LOCK_FUNC_MODULES: for path in settings.LOCK_FUNC_MODULES:
imp(path, split=False) importlib.import_module(path, split=False)
# cmdsets # cmdsets
deprstring = "settings.%s should be renamed to %s. If defaults are used, " \ deprstring = "settings.%s should be renamed to %s. If defaults are used, " \
@ -541,12 +648,13 @@ def error_check_python_modules():
if not cmdsethandler.import_cmdset(settings.CMDSET_CHARACTER, None): print "Warning: CMDSET_CHARACTER failed to load" if not cmdsethandler.import_cmdset(settings.CMDSET_CHARACTER, None): print "Warning: CMDSET_CHARACTER failed to load"
if not cmdsethandler.import_cmdset(settings.CMDSET_PLAYER, None): print "Warning: CMDSET_PLAYER failed to load" if not cmdsethandler.import_cmdset(settings.CMDSET_PLAYER, None): print "Warning: CMDSET_PLAYER failed to load"
# typeclasses # typeclasses
imp(settings.BASE_PLAYER_TYPECLASS) importlib.import_module(settings.BASE_PLAYER_TYPECLASS)
imp(settings.BASE_OBJECT_TYPECLASS) importlib.import_module(settings.BASE_OBJECT_TYPECLASS)
imp(settings.BASE_CHARACTER_TYPECLASS) importlib.import_module(settings.BASE_CHARACTER_TYPECLASS)
imp(settings.BASE_ROOM_TYPECLASS) importlib.import_module(settings.BASE_ROOM_TYPECLASS)
imp(settings.BASE_EXIT_TYPECLASS) importlib.import_module(settings.BASE_EXIT_TYPECLASS)
imp(settings.BASE_SCRIPT_TYPECLASS) importlib.import_module(settings.BASE_SCRIPT_TYPECLASS)
def create_database(): def create_database():
from django.core.management import call_command from django.core.management import call_command
@ -554,32 +662,25 @@ def create_database():
call_command("migrate", interactive=False) call_command("migrate", interactive=False)
print "\n ... database initialized.\n" print "\n ... database initialized.\n"
def create_superuser(): def create_superuser():
from django.core.management import call_command from django.core.management import call_command
print "\nCreate a superuser below. The superuser is Player #1, the 'owner' account of the server.\n" print "\nCreate a superuser below. The superuser is Player #1, the 'owner' account of the server.\n"
call_command("createsuperuser", interactive=True) call_command("createsuperuser", interactive=True)
def check_database(automigrate=False): def check_database(automigrate=False):
# Check so a database exists and is accessible # Check so a database exists and is accessible
from django.db import DatabaseError from django.db import DatabaseError
from src.players.models import PlayerDB from src.players.models import PlayerDB
try: try:
superuser = PlayerDB.objects.get(id=1) PlayerDB.objects.get(id=1)
except DatabaseError, e: except DatabaseError, e:
if automigrate: if automigrate:
create_database() create_database()
create_superuser() create_superuser()
else: else:
print """ print ERROR_DATABASE.format(traceback=e)
Your database does not seem to be set up correctly.
(error was '%s')
Try to run
python evennia.py
to initialize the database according to your settings.
""" % e
sys.exit() sys.exit()
except PlayerDB.DoesNotExist: except PlayerDB.DoesNotExist:
# no superuser yet. We need to create it. # no superuser yet. We need to create it.
@ -587,71 +688,60 @@ def check_database(automigrate=False):
def main(): def main():
""" """
This handles command line input. Run the evennia main program.
""" """
parser = OptionParser(usage="%prog [-i] start|stop|reload|menu [server|portal]|manager args", # set up argument parser
parser = ArgumentParser(#usage="%prog [-i] start|stop|reload|menu [server|portal]|manager args",
description=CMDLINE_HELP) description=CMDLINE_HELP)
parser.add_option('-i', '--interactive', action='store_true', parser.add_argument('-i', '--interactive', action='store_true',
dest='interactive', default=False, dest='interactive', default=False,
help="Start given processes in interactive mode.") help="Start given processes in interactive mode.")
parser.add_option('-v', '--version', action='store_true', parser.add_argument('-v', '--version', action='store_true',
dest='show_version', default=False, dest='show_version', default=False,
help="Show version info.") help="Show version info.")
parser.add_argument('--init', action='store', dest="init", metavar="dirname")
parser.add_argument('-c', '--config', action='store', dest="config", default=None)
parser.add_argument("mode", default="menu")
parser.add_argument("service", choices=["all", "server", "portal"], default="all")
options, args = parser.parse_args() args = parser.parse_args()
if not args: # handle arguments
if options.show_version:
print show_version_info()
return
mode = "menu"
service = 'all'
if args:
mode = args[0]
service = "all"
if len(args) > 1:
service = args[1]
if mode in ["start", "menu"]: if args.show_version:
check_database(True) print show_version_info()
elif mode not in ["stop"]:
check_database(False)
if mode not in ['menu', 'start', 'reload', 'stop']: mode, service = args.mode, args.service
from django.core.management import call_command
call_command(mode) if args.init:
sys.exit() create_game_directory(args.init)
if service not in ['server', 'portal', 'all']:
print "service should be none, 'server', 'portal' or 'all'."
sys.exit() sys.exit()
# this must be done first - it sets up all the global properties
# and initializes django for the game directory
init_game_directory(CURRENT_DIR)
if mode == 'menu': if mode == 'menu':
# launch menu # launch menu for operation
cmdstr = run_menu() check_database(True)
run_menu()
elif mode in ('start', 'reload', 'stop'):
# operate the server directly
if mode != "stop":
check_database(False)
server_operation(mode, service, args.interactive)
else: else:
# handle command-line arguments # pass-through to django manager
cmdstr = handle_args(options, mode, service) from django.core.management import call_command
if cmdstr: call_command(mode)
# call the runner.
cmdstr.append('start')
Popen(cmdstr)
if __name__ == '__main__': if __name__ == '__main__':
# start Evennia # start Evennia from the command line
if _CREATED_SETTINGS:
# if settings were created, info has already been printed.
sys.exit()
from src.utils.utils import check_evennia_dependencies
if check_evennia_dependencies(): if check_evennia_dependencies():
if len(sys.argv) > 1 and sys.argv[1] in ('runserver', 'testserver'): if len(sys.argv) > 1 and sys.argv[1] in ('runserver', 'testserver'):
print """ print WARNING_RUNSERVER
WARNING: There is no need to run the Django development
webserver to test out Evennia web features (the web client
will in fact not work since the Django test server knows
nothing about MUDs). Instead, just start Evennia with the
webserver component active (this is the default).
"""
main() main()