Made the evennia launcher pass through the management options in a better way. Also made the superuser creation more straightforward and handled flushed databases in a better way.

This commit is contained in:
Griatch 2015-02-08 23:36:53 +01:00
parent 16b7a79573
commit 2aafafc09c
5 changed files with 91 additions and 35 deletions

View file

@ -92,12 +92,32 @@ CREATED_NEW_GAMEDIR = \
"""
ERROR_INPUT = \
"""
The argument(s)
{args}
is not recognized by Evennia nor Django. Use -h for help.
"""
ERROR_NO_GAMEDIR = \
"""
No Evennia settings file was found. You must run this command from
inside a valid game directory first created with --init.
"""
WARNING_MOVING_SUPERUSER = \
"""
Evennia expects a Player superuser with id=1. No such Player was
found. However, another superuser ('{other_key}', id={other_id})
was found in the database. If you just created this superuser and
still see this text it is probably due to the database being
flushed recently - in this case the database's internal
auto-counter might just start from some value higher than one.
We will fix this by assigning the id 1 to Player '{other_key}'.
Please confirm this is acceptable before continuing.
"""
WARNING_RUNSERVER = \
"""
WARNING: There is no need to run the Django development
@ -127,7 +147,7 @@ ERROR_DATABASE = \
Your database does not seem to be set up correctly.
(error was '{traceback}')
Standing in your game directory, try to run
Standing in your game directory, run
evennia migrate
@ -430,7 +450,7 @@ def create_superuser():
django.core.management.call_command("createsuperuser", interactive=True)
def check_database(exit_on_error=False):
def check_database():
"""
Check database exists
"""
@ -441,19 +461,46 @@ def check_database(exit_on_error=False):
# database exists and seems set up. Initialize evennia.
import evennia
evennia.init()
else:
if exit_on_error:
print ERROR_DATABASE.format(traceback=e)
sys.exit()
return False
return True
# Try to get Player#1
from evennia.players.models import PlayerDB
try:
PlayerDB.objects.get(id=1)
except django.db.utils.OperationalError, e:
print ERROR_DATABASE.format(traceback=e)
sys.exit()
except PlayerDB.DoesNotExist:
# no superuser yet. We need to create it.
create_superuser()
other_superuser = PlayerDB.objects.filter(is_superuser=True)
if other_superuser:
# Another superuser was found, but not with id=1. This may
# happen if using flush (the auto-id starts at a higher
# value). Wwe copy this superuser into id=1. To do
# this we must deepcopy it, delete it then save the copy
# with the new id. This allows us to avoid the UNIQUE
# constraint on usernames.
other = other_superuser[0]
other_id = other.id
other_key = other.username
print WARNING_MOVING_SUPERUSER.format(other_key=other_key,
other_id=other_id)
res = ""
while res.upper() != "Y":
# ask for permission
res = raw_input("Continue [Y]/N: ")
if res.upper() == "N":
sys.exit()
elif not res:
break
# continue with the
from copy import deepcopy
new = deepcopy(other)
other.delete()
new.id = 1
new.save()
else:
create_superuser()
check_database()
return True
@ -854,16 +901,16 @@ def main():
help="Start given server component under the Python profiler.")
parser.add_argument('--dummyrunner', nargs=1, action='store', dest='dummyrunner', metavar="N",
help="Tests a running server by connecting N dummy players to it.")
parser.add_argument("mode", metavar="option", nargs='?', default="help",
help="Operational mode or management option. Commonly start, stop, reload, migrate, or menu (default).")
parser.add_argument("service", metavar="component", nargs='?', choices=["all", "server", "portal"], default="all",
parser.add_argument("option", nargs='?', default="noop",
help="Operational mode or management option.")
parser.add_argument("service", metavar="component", nargs='?', default="all",
help="Which server component to operate on. One of server, portal or all (default).")
args = parser.parse_args()
args, unknown_args = parser.parse_known_args()
# handle arguments
mode, service = args.mode, args.service
option, service = args.option, args.service
check_main_evennia_dependencies()
@ -874,31 +921,43 @@ def main():
sys.exit()
if args.show_version:
print show_version_info(mode=="help")
print show_version_info(option=="help")
sys.exit()
if mode == "help" and not args.dummyrunner:
if option == "help" and not args.dummyrunner:
print ABOUT_INFO
sys.exit()
check_db = not mode == "migrate"
# this must be done first - it sets up all the global properties
# and initializes django for the game directory
init_game_directory(CURRENT_DIR, check_db=check_db)
if args.dummyrunner:
# launch the dummy runner
init_game_directory(CURRENT_DIR, check_db=True)
run_dummyrunner(args.dummyrunner[0])
elif mode == 'menu':
elif option == 'menu':
# launch menu for operation
init_game_directory(CURRENT_DIR, check_db=True)
run_menu()
elif mode in ('start', 'reload', 'stop'):
elif option in ('start', 'reload', 'stop'):
# operate the server directly
server_operation(mode, service, args.interactive, args.profiler)
else:
init_game_directory(CURRENT_DIR, check_db=True)
server_operation(option, service, args.interactive, args.profiler)
elif option != "noop":
# pass-through to django manager
if mode in ('runserver', 'testserver'):
init_game_directory(CURRENT_DIR, check_db=False)
if option in ('runserver', 'testserver'):
print WARNING_RUNSERVER
django.core.management.call_command(mode)
args = [option]
kwargs = {}
if service not in ("all", "server", "portal"):
args.append(service)
if unknown_args:
for arg in unknown_args:
if arg.startswith("--"):
kwargs[arg.lstrip("--")] = True
else:
args.append(arg)
try:
django.core.management.call_command(*args, **kwargs)
except django.core.management.base.CommandError:
print ERROR_INPUT.format(args=" ".join(args))
if __name__ == '__main__':

View file

@ -70,10 +70,10 @@ def create_objects():
nohome=True)
god_character.id = 1
god_character.save()
god_character.db.desc = _('This is User #1.')
god_character.locks.add("examine:perm(Immortals);edit:false();delete:false();boot:false();msg:all();puppet:false()")
god_character.permissions.add("Immortals")
god_character.save()
god_player.attributes.add("_first_login", True)
god_player.attributes.add("_last_puppet", god_character)
@ -82,6 +82,7 @@ def create_objects():
room_typeclass = settings.BASE_ROOM_TYPECLASS
limbo_obj = create.create_object(room_typeclass, _('Limbo'), nohome=True)
limbo_obj.id = 2
limbo_obj.save()
string = \
"Welcome to your new {wEvennia{n-based game. From here you are ready " \
"to begin development. Visit http://evennia.com if you should need " \

View file

@ -36,7 +36,7 @@ from evennia.utils.utils import mod_import
class EvenniaTestSuiteRunner(DjangoTestSuiteRunner):
"""
This test runner only runs tests on the apps specified in evennia/ and game/ to
This test runner only runs tests on the apps specified in evennia/
avoid running the large number of tests defined by Django
"""
def build_suite(self, test_labels, extra_tests=None, **kwargs):
@ -67,11 +67,9 @@ def suite():
tsuite.addTest(unittest.defaultTestLoader.loadTestsFromModule(locktests))
tsuite.addTest(unittest.defaultTestLoader.loadTestsFromModule(utiltests))
# load tests from the evennia/tests central location
for path in glob.glob(os.path.join(settings.EVENNIA_DIR, "tests", "*.py")):
testmod = mod_import(path)
tsuite.addTest(unittest.defaultTestLoader.loadTestsFromModule(testmod))
#from evennia.tests import test_commands_cmdhandler
#tsuite.addTest(unittest.defaultTestLoader.loadTestsFromModule(test_commands_cmdhandler))
return tsuite

View file

@ -438,8 +438,6 @@ class TypedObject(SharedMemoryModel):
"Scrambling method for already deleted objects"
raise ObjectDoesNotExist("This object was already deleted!")
_is_deleted = False # this is checked by db_* wrappers
def delete(self):
"Cleaning up handlers on the typeclass level"
global TICKER_HANDLER
@ -455,7 +453,6 @@ class TypedObject(SharedMemoryModel):
# scrambling properties
self.delete = self._deleted
self._is_deleted = True
super(TypedObject, self).delete()
#

View file

@ -310,6 +310,7 @@ class SharedMemoryModel(Model):
Delete the object, clearing cache
"""
self.flush_from_cache()
self._is_deleted = True
super(SharedMemoryModel, self).delete(*args, **kwargs)
def save(self, *args, **kwargs):