backup.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. '''Dump the SQLite and Redis db.'''
  2. import gzip
  3. import io
  4. import json
  5. import os.path
  6. import subprocess
  7. from terroroftinytown.tracker.bootstrap import Bootstrap
  8. import shutil
  9. class BackupBootstrap(Bootstrap):
  10. def start(self, *args, **kwargs):
  11. super().start(*args, **kwargs)
  12. self.setup_redis()
  13. self.dump()
  14. def setup_args(self):
  15. super().setup_args()
  16. self.arg_parser.add_argument('dest_dir')
  17. def dump(self):
  18. if not self.config['database']['path'].startswith('sqlite:///'):
  19. raise Exception('Only SQLite is supported')
  20. if not os.path.isdir(self.args.dest_dir):
  21. raise Exception('Destination is not a directory.')
  22. filename = self.config['database']['path'].replace('sqlite:///', '')
  23. dump_filename = os.path.join(self.args.dest_dir, 'tinytown.sql.gz')
  24. temp_dump_filename = dump_filename + '-new'
  25. print('Begin db dump.', filename, dump_filename)
  26. with gzip.GzipFile(temp_dump_filename, mode='wb') as gzip_file:
  27. proc = subprocess.Popen(['sqlite3', filename, '.dump'],
  28. stdout=subprocess.PIPE)
  29. shutil.copyfileobj(proc.stdout, gzip_file)
  30. proc.communicate()
  31. if proc.returncode:
  32. raise Exception('Proc returned {}'.format(proc.returncode))
  33. os.rename(temp_dump_filename, dump_filename)
  34. print('Done')
  35. dump_filename = os.path.join(self.args.dest_dir, 'tinytown.redis.gz')
  36. temp_dump_filename = dump_filename + '-new'
  37. print('Begin redis dump', dump_filename)
  38. keys = self.redis.keys(self.config['redis'].get('prefix', '') + '*')
  39. data = {}
  40. for key in keys:
  41. data[key.decode('ascii')] = self.redis.dump(key).decode('latin-1')
  42. with gzip.GzipFile(temp_dump_filename, mode='wb') as gzip_file:
  43. json.dump(data, io.TextIOWrapper(gzip_file))
  44. os.rename(temp_dump_filename, dump_filename)
  45. print('Done')
  46. if __name__ == '__main__':
  47. BackupBootstrap().start()