#! @PYTHON@ # # Copyright (C) 1998-2005 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. """Dump the contents of any Mailman `database' file. Usage: %(PROGRAM)s [options] filename Options: --marshal/-m Assume the file contains a Python marshal, overridding any automatic guessing. --pickle/-p Assume the file contains a Python pickle, overridding any automatic guessing. --noprint/-n Don't attempt to pretty print the object. This is useful if there's some problem with the object and you just want to get an unpickled representation. Useful with `python -i bin/dumpdb '. In that case, the root of the tree will be left in a global called "msg". --help/-h Print this help message and exit If the filename ends with `.db', then it is assumed that the file contains a Python marshal. If the file ends with `.pck' then it is assumed to contain a Python pickle. In either case, if you want to override the default assumption -- or if the file ends in neither suffix -- use the -p or -m flags. """ import os import sys import getopt import pprint from cPickle import load from types import StringType import paths # Import this /after/ paths so that the sys.path is properly hacked from email.Generator import Generator from Mailman.i18n import _ PROGRAM = sys.argv[0] COMMASPACE = ', ' try: True, False except NameError: True = 1 False = 0 def usage(code, msg=''): if code: fd = sys.stderr else: fd = sys.stdout print >> fd, _(__doc__) % globals() if msg: print >> fd, msg sys.exit(code) def main(): try: opts, args = getopt.getopt(sys.argv[1:], 'mphn', ['marshal', 'pickle', 'help', 'noprint']) except getopt.error, msg: usage(1, msg) # Options. # None == guess, 0 == pickle, 1 == marshal filetype = None doprint = True for opt, arg in opts: if opt in ('-h', '--help'): usage(0) elif opt in ('-p', '--pickle'): filetype = 0 elif opt in ('-m', '--marshal'): filetype = 1 elif opt in ('-n', '--noprint'): doprint = False if len(args) < 1: usage(1, _('No filename given.')) elif len(args) > 1: pargs = COMMASPACE.join(args) usage(1, _('Bad arguments: %(pargs)s')) else: filename = args[0] if filetype is None: if filename.endswith('.db'): filetype = 1 elif filename.endswith('.pck'): filetype = 0 else: usage(1, _('Please specify either -p or -m.')) # Handle dbs pp = pprint.PrettyPrinter(indent=4) if filetype == 1: # BAW: this probably doesn't work if there are mixed types of .db # files (i.e. some marshals, some bdbs). d = DumperSwitchboard().read(filename) if doprint: pp.pprint(d) return d else: fp = open(filename) m = [] try: cnt = 1 if doprint: print _('[----- start pickle file -----]') while True: try: obj = load(fp) except EOFError: if doprint: print _('[----- end pickle file -----]') break if doprint: print _('<----- start object %(cnt)s ----->') if isinstance(obj, StringType): print obj else: pp.pprint(obj) cnt += 1 m.append(obj) finally: fp.close() return m if __name__ == '__main__': msg = main()