123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- '''Dump the SQLite and Redis db.'''
- import gzip
- import io
- import json
- import os.path
- import subprocess
- from terroroftinytown.tracker.bootstrap import Bootstrap
- import shutil
- class BackupBootstrap(Bootstrap):
- def start(self, *args, **kwargs):
- super().start(*args, **kwargs)
- self.setup_redis()
- self.dump()
- def setup_args(self):
- super().setup_args()
- self.arg_parser.add_argument('dest_dir')
- def dump(self):
- if not self.config['database']['path'].startswith('sqlite:///'):
- raise Exception('Only SQLite is supported')
- if not os.path.isdir(self.args.dest_dir):
- raise Exception('Destination is not a directory.')
- filename = self.config['database']['path'].replace('sqlite:///', '')
- dump_filename = os.path.join(self.args.dest_dir, 'tinytown.sql.gz')
- temp_dump_filename = dump_filename + '-new'
- print('Begin db dump.', filename, dump_filename)
- with gzip.GzipFile(temp_dump_filename, mode='wb') as gzip_file:
- proc = subprocess.Popen(['sqlite3', filename, '.dump'],
- stdout=subprocess.PIPE)
- shutil.copyfileobj(proc.stdout, gzip_file)
- proc.communicate()
- if proc.returncode:
- raise Exception('Proc returned {}'.format(proc.returncode))
- os.rename(temp_dump_filename, dump_filename)
- print('Done')
- dump_filename = os.path.join(self.args.dest_dir, 'tinytown.redis.gz')
- temp_dump_filename = dump_filename + '-new'
- print('Begin redis dump', dump_filename)
- keys = self.redis.keys(self.config['redis'].get('prefix', '') + '*')
- data = {}
- for key in keys:
- data[key.decode('ascii')] = self.redis.dump(key).decode('latin-1')
- with gzip.GzipFile(temp_dump_filename, mode='wb') as gzip_file:
- json.dump(data, io.TextIOWrapper(gzip_file))
- os.rename(temp_dump_filename, dump_filename)
- print('Done')
- if __name__ == '__main__':
- BackupBootstrap().start()
|