#!/usr/bin/env python3
# -*- encoding: UTF8 -*-
"""
P4TreeMap.py - print out tree-related information on file sizes in a
repository or part of one.
Data can be output in JSON hierarchy or CSV flat file.
Main usage is as part of p4webtreemap.py which is a Flask app to display
the results on a web page.
"""
from __future__ import print_function
import sys
import P4
import argparse
import os
import logging
DEFAULT_VERBOSITY = 'INFO'
DEFAULT_LOG_FILE = 'log-p4treemap.log'
LOGGER_NAME = 'LOG2SQL'
class P4TreeMap():
def __init__(self, options, outstream=None):
self.options = options
self.options.logfile = DEFAULT_LOG_FILE
self.p4 = P4.P4()
if options.port:
self.p4.port = options.port
if options.user:
self.p4.user = options.user
if outstream:
self.outstream = outstream
else:
self.outstream = sys.stdout
if options.root:
os.chdir(options.root)
self.init_logger()
self.logger.debug("p4treemap.py: %s" % self.options)
self.logger.debug("Currdir: %s" % os.getcwd())
self.p4.connect()
def init_logger(self):
self.logger = logging.getLogger(LOGGER_NAME)
self.logger.setLevel(self.options.verbosity)
outformatter = logging.Formatter('%(message)s')
ch = logging.StreamHandler(self.outstream)
ch.setLevel(logging.INFO)
ch.setFormatter(outformatter)
self.logger.addHandler(ch)
if self.options.verbosity != logging.INFO and self.options.logfile:
formatter = logging.Formatter('%(asctime)s:%(levelname)s %(message)s')
fh = logging.FileHandler(self.options.logfile, mode='w')
fh.setFormatter(formatter)
self.logger.addHandler(fh)
def output(self, line):
self.logger.info(line)
def run(self):
seen = {}
sep = "\t"
self.output("id{}value".format(sep))
for f in self.p4.run_sizes(self.options.path):
path = f['depotFile'][2:] # strip //
parts = path.split('/')
for i in range(len(parts)):
dir = '/'.join(parts[:i])
if dir and not dir in seen:
self.output("{}{}".format(dir, sep))
seen[dir] = 1
self.output("{}{}{}".format(path, sep, f['fileSize']))
def main():
parser = argparse.ArgumentParser(add_help=True)
parser.add_argument('-p', '--port', help="Perforce P4PORT to use", default=None)
parser.add_argument('-u', '--user', help="Perforce P4USER to use", default=None)
parser.add_argument('-r', '--root', help="Root of a DVCS server to use", default=None)
parser.add_argument('-m', '--max', help="Maximum levels to recurse down, 0 = all", default=4)
parser.add_argument('path', help="Perforce depot path to analyse. Default //...", default="//...")
parser.add_argument('-v', '--verbosity', nargs='?', const="INFO", default=DEFAULT_VERBOSITY,
choices=('DEBUG', 'INFO', 'WARNING', 'ERROR', 'FATAL'),
help="Output verbosity level. Default is: " + DEFAULT_VERBOSITY)
try:
options = parser.parse_args()
except Exception as e:
parser.print_help()
sys.exit(1)
tree = P4TreeMap(options)
tree.run()
if __name__ == '__main__':
main()