simpler spec autosave/backup

This commit is contained in:
Darren Ranalli 2003-10-16 00:36:22 +00:00
parent 8326fd6198
commit a9aaed8d15
2 changed files with 60 additions and 47 deletions

View File

@ -20,7 +20,6 @@ class DistributedLevelAI(DistributedObjectAI.DistributedObjectAI,
self.zoneId = zoneId
if __debug__:
self.modified = 0
self.makeBackup = 1
def generate(self, levelSpec):
self.notify.debug('generate')
@ -41,7 +40,7 @@ class DistributedLevelAI(DistributedObjectAI.DistributedObjectAI,
def delete(self):
self.notify.debug('delete')
if __debug__:
self.saveSpec()
self.removeBackupTask()
self.destroyLevel()
DistributedObjectAI.DistributedObjectAI.delete(self)
@ -103,35 +102,43 @@ class DistributedLevelAI(DistributedObjectAI.DistributedObjectAI,
self.levelSpec.setAttribChange(entId, attribName, value, username)
self.modified = 1
self.scheduleSave()
self.scheduleAutosave()
SavePeriod = simbase.config.GetInt('factory-save-period', 10)
BackupPeriod = simbase.config.GetInt('factory-backup-period-minutes',5)
# backups are made every N minutes, starting from the time that
# the first edit is made
AutosavePeriod = simbase.config.GetFloat(
'level-autosave-period-minutes', 5)
def scheduleSave(self):
if hasattr(self, 'saveTask'):
def scheduleAutosave(self):
if hasattr(self, 'autosaveTask'):
return
self.saveTask = taskMgr.doMethodLater(
DistributedLevelAI.SavePeriod,
self.saveSpec,
self.uniqueName('saveSpec'))
self.autosaveTaskName = self.uniqueName('saveSpec')
self.autosaveTask = taskMgr.doMethodLater(
DistributedLevelAI.AutosavePeriod * 60,
self.autosaveSpec,
self.autosaveTaskName)
def removeAutosaveTask(self):
if hasattr(self, 'autosaveTask'):
taskMgr.remove(self.autosaveTaskName)
del self.autosaveTask
def autosaveSpec(self, task=None):
self.removeAutosaveTask()
if self.modified:
DistributedLevelAI.notify.info('autosaving spec')
filename = self.levelSpec.getFilename()
filename = '%s.autosave' % filename
self.levelSpec.saveToDisk(filename, makeBackup=0)
def saveSpec(self, task=None):
DistributedLevelAI.notify.info('saving spec')
if hasattr(self, 'saveTask'):
del self.saveTask
self.removeAutosaveTask()
if not self.modified:
DistributedLevelAI.notify.info('no changes to save')
return
self.levelSpec.saveToDisk(createBackup=self.makeBackup)
self.levelSpec.saveToDisk()
self.modified = 0
self.makeBackup = 0
def setMakeBackup(task, self=self):
self.makeBackup = 1
self.backupTask = taskMgr.doMethodLater(
DistributedLevelAI.BackupPeriod * 60,
setMakeBackup,
self.uniqueName('setMakeBackup'))
def requestCurrentLevelSpec(self, specHash, entTypeRegHash):
senderId = self.air.msgSender

View File

@ -3,6 +3,8 @@
import DirectNotifyGlobal
from PythonUtil import list2dict, uniqueElements
import string
if __debug__:
import os
class LevelSpec:
"""contains spec data for a level, is responsible for handing the data
@ -138,42 +140,32 @@ class LevelSpec:
# name of module that should be imported by spec py file
return 'SpecImports'
def saveToDisk(self, filename=None, createBackup=1):
"""returns zero on failure"""
import os
def getFilename(self):
return self.filename
def privGetBackupFilename(self):
return '%s.bak' % self.getFilename()
def saveToDisk(self, filename=None, makeBackup=1):
"""returns zero on failure"""
if filename is None:
filename = self.filename
if createBackup:
if makeBackup and self.privFileExists(filename):
# create a backup
try:
# does the file exist?
exists = 0
try:
os.stat(filename)
exists = 1
except OSError:
pass
if exists:
def getBackupFilename(num, filename=filename):
return '%s.%03i' % (filename, num)
numBackups = 200
try:
os.unlink(getBackupFilename(numBackups-1))
except OSError:
pass
for i in range(numBackups-1,0,-1):
try:
os.rename(getBackupFilename(i-1),
getBackupFilename(i))
except OSError:
pass
os.rename(filename, getBackupFilename(0))
backupFilename = self.privGetBackupFilename()
self.privRemoveFile(backupFilename)
os.rename(filename, backupFilename)
except OSError, e:
LevelSpec.notify.warning(
'error during backup: %s' % str(e))
self.privRemoveFile(filename)
self.privSaveToDisk(filename)
def privSaveToDisk(self, filename):
"""internal. saves spec to file. returns zero on failure"""
retval = 1
# wb to create a UNIX-format file
f = file(filename, 'wb')
@ -184,6 +176,20 @@ class LevelSpec:
f.close()
return retval
def privFileExists(self, filename):
try:
os.stat(filename)
return 1
except OSError:
return 0
def privRemoveFile(self, filename):
try:
os.remove(filename)
return 1
except OSError:
return 0
def getPrettyString(self):
"""Returns a string that contains the spec data, nicely formatted.
This should be used when writing the spec out to file."""