archiver.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. import argparse
  2. import logging
  3. import os
  4. import sys
  5. from .archive import Archive
  6. from .store import Store
  7. from .cache import Cache
  8. from .crypto import CryptoManager, KeyChain
  9. from .helpers import location_validator, format_file_size, LevelFilter
  10. class Archiver(object):
  11. def open_store(self, location):
  12. return Store(location.path)
  13. def exit_code_from_logger(self):
  14. return 1 if self.level_filter.count.get('ERROR') else 0
  15. def do_init(self, args):
  16. Store(args.store.path, create=True)
  17. return self.exit_code_from_logger()
  18. def do_create(self, args):
  19. store = self.open_store(args.archive)
  20. keychain = KeyChain(args.keychain)
  21. crypto = CryptoManager(keychain)
  22. archive = Archive(store, crypto)
  23. cache = Cache(store, archive.crypto)
  24. archive.create(args.archive.archive, args.paths, cache)
  25. return self.exit_code_from_logger()
  26. def do_extract(self, args):
  27. store = self.open_store(args.archive)
  28. keychain = KeyChain(args.keychain)
  29. crypto = CryptoManager(keychain)
  30. archive = Archive(store, crypto, args.archive.archive)
  31. archive.extract(args.dest)
  32. return self.exit_code_from_logger()
  33. def do_delete(self, args):
  34. store = self.open_store(args.archive)
  35. keychain = KeyChain(args.keychain)
  36. crypto = CryptoManager(keychain)
  37. archive = Archive(store, crypto, args.archive.archive)
  38. cache = Cache(store, archive.crypto)
  39. archive.delete(cache)
  40. return self.exit_code_from_logger()
  41. def do_list(self, args):
  42. store = self.open_store(args.src)
  43. keychain = KeyChain(args.keychain)
  44. crypto = CryptoManager(keychain)
  45. if args.src.archive:
  46. archive = Archive(store, crypto, args.src.archive)
  47. archive.list()
  48. else:
  49. for archive in Archive.list_archives(store, crypto):
  50. print '%(name)-20s %(time)s' % archive.metadata
  51. return self.exit_code_from_logger()
  52. def do_verify(self, args):
  53. store = self.open_store(args.archive)
  54. keychain = KeyChain(args.keychain)
  55. crypto = CryptoManager(keychain)
  56. archive = Archive(store, crypto, args.archive.archive)
  57. archive.verify()
  58. return self.exit_code_from_logger()
  59. def do_info(self, args):
  60. store = self.open_store(args.archive)
  61. keychain = KeyChain(args.keychain)
  62. crypto = CryptoManager(keychain)
  63. archive = Archive(store, crypto, args.archive.archive)
  64. cache = Cache(store, archive.crypto)
  65. osize, csize, usize = archive.stats(cache)
  66. print 'Name:', archive.metadata['name']
  67. print 'Hostname:', archive.metadata['hostname']
  68. print 'Username:', archive.metadata['username']
  69. print 'Time:', archive.metadata['time']
  70. print 'Command line:', ' '.join(archive.metadata['cmdline'])
  71. print 'Number of Files:', len(archive.items)
  72. print 'Original size:', format_file_size(osize)
  73. print 'Compressed size:', format_file_size(csize)
  74. print 'Unique data:', format_file_size(usize)
  75. return self.exit_code_from_logger()
  76. def do_keychain_generate(self, args):
  77. return KeyChain.generate(args.keychain)
  78. def do_keychain_restrict(self, args):
  79. return KeyChain(args.keychain).restrict(args.output)
  80. def do_keychain_chpass(self, args):
  81. return KeyChain(args.keychain).chpass()
  82. def run(self, args=None):
  83. default_keychain = os.path.join(os.path.expanduser('~'),
  84. '.darc', 'keychain')
  85. parser = argparse.ArgumentParser(description='DARC - Deduplicating Archiver')
  86. parser.add_argument('-k', '--keychain', dest='keychain', type=str,
  87. default=default_keychain,
  88. help='Keychain to use')
  89. parser.add_argument('-v', '--verbose', dest='verbose', action='store_true',
  90. default=False,
  91. help='Verbose output')
  92. subparsers = parser.add_subparsers(title='Available subcommands')
  93. subparser = subparsers.add_parser('keychain')
  94. subsubparsers = subparser.add_subparsers(title='Available subcommands')
  95. subparser = subsubparsers.add_parser('generate')
  96. subparser.set_defaults(func=self.do_keychain_generate)
  97. subparser = subsubparsers.add_parser('restrict')
  98. subparser.add_argument('output', metavar='OUTPUT', type=str,
  99. help='Keychain to create')
  100. subparser.set_defaults(func=self.do_keychain_restrict)
  101. subparser = subsubparsers.add_parser('change-password')
  102. subparser.set_defaults(func=self.do_keychain_chpass)
  103. subparser = subparsers.add_parser('init')
  104. subparser.set_defaults(func=self.do_init)
  105. subparser.add_argument('store', metavar='STORE',
  106. type=location_validator(archive=False),
  107. help='Store to initialize')
  108. subparser = subparsers.add_parser('create')
  109. subparser.set_defaults(func=self.do_create)
  110. subparser.add_argument('archive', metavar='ARCHIVE',
  111. type=location_validator(archive=True),
  112. help='Archive to create')
  113. subparser.add_argument('paths', metavar='PATH', nargs='+', type=str,
  114. help='Paths to add to archive')
  115. subparser = subparsers.add_parser('extract')
  116. subparser.set_defaults(func=self.do_extract)
  117. subparser.add_argument('archive', metavar='ARCHIVE',
  118. type=location_validator(archive=True),
  119. help='Archive to create')
  120. subparser.add_argument('dest', metavar='DEST', type=str, nargs='?',
  121. help='Where to extract files')
  122. subparser = subparsers.add_parser('delete')
  123. subparser.set_defaults(func=self.do_delete)
  124. subparser.add_argument('archive', metavar='ARCHIVE',
  125. type=location_validator(archive=True),
  126. help='Archive to delete')
  127. subparser = subparsers.add_parser('list')
  128. subparser.set_defaults(func=self.do_list)
  129. subparser.add_argument('src', metavar='SRC', type=location_validator(),
  130. help='Store/Archive to list contents of')
  131. subparser= subparsers.add_parser('verify')
  132. subparser.set_defaults(func=self.do_verify)
  133. subparser.add_argument('archive', metavar='ARCHIVE',
  134. type=location_validator(archive=True),
  135. help='Archive to verity integrity of')
  136. subparser= subparsers.add_parser('info')
  137. subparser.set_defaults(func=self.do_info)
  138. subparser.add_argument('archive', metavar='ARCHIVE',
  139. type=location_validator(archive=True),
  140. help='Archive to display information about')
  141. args = parser.parse_args(args)
  142. if args.verbose:
  143. logging.basicConfig(level=logging.INFO, format='%(message)s')
  144. else:
  145. logging.basicConfig(level=logging.WARNING, format='%(message)s')
  146. self.level_filter = LevelFilter()
  147. logging.getLogger('').addFilter(self.level_filter)
  148. return args.func(args)
  149. def main():
  150. archiver = Archiver()
  151. sys.exit(archiver.run())
  152. if __name__ == '__main__':
  153. main()