#!/usr/bin/env python2.2

# print html code for a directory (unix)

import sys
import os
import re


# a helper class:
class Bunch:
  def __init__( self, **kwds ): self.__dict__.update( kwds )


argc = len( sys.argv ) - 1
if argc < 2:
  print "Usage  : dirtree2html '<start directory>' '<relative img path> [create_links]'"
  print
  print "Example: dirtree2html someproject 'img/'"
  sys.exit()

  # -----------------------------------------------------------------------
base_path = sys.argv[ 1 ]
icons_base_url = sys.argv[ 2 ]

create_links = 0
if argc == 3:
  create_links = sys.argv[ 3 ]
# -----------------------------------------------------------------------

# Customize your copy of this program in this block:

# Color codes:
#                     id    color     some_name       openHTML  closeHTML

# important: id=0 : default, id=1: directory !

table_headers = ( ("Filename",150), "Size", "Type" )

color_codes_info = [ ( 0, '#000000', 'default',       '',    ''     ),
                     ( 1, '#000000', 'directory',     '<i>', '</i>' ),
                     ( 2, '#000000', 'unknown files', '',    ''     ),
                     ( 3, '#00DD00', 'executables',   '<b>', '</b>' ),
                     ( 4, '#009999', 'text files',    '',    ''     ),
                   ]


# Texts and icons for directories:

folder_info = ( "", "directory", 1, "folder.png" )


# Texts and icons for file extensions:

extensions_info = [ ("py",   0, "Python source"    , "textfile.png"),
                    ("py~",  0, "Old python source", "textfile.png"),
                    ("pyc",  0, "Python byte code" , "textfile.png"),
                    ("pl",   0, "perlsource"       , "textfile.png"),
                    ("c",    0, "C source"         , "textfile.png"),
                    ("cpp",  0, "C++ source"       , "textfile.png"),
                    ("cc",   0, "C++ source"       , "textfile.png"),
                    ("java", 0, "Java source"      , "textfile.png"),
                    ("class",0, "A class file"     , "textfile.png"),
                    ("ply",  0, "plynets data"     , "somefile.png"),
                    ("txt",  4, "Text"             , "textfile.png"),
                    ("tgz",  0, "TAR GZ archive"   , "somefile.png"),
                    ("png",  0, "Graphics"         , "gfxfile.png"),
                    ("gif",  0, "Graphics"         , "gfxfile.png"),
                    ("jpg",  0, "Graphics"         , "gfxfile.png"),
                    ("tif",  0, "Graphics"         , "gfxfile.png"),
                    ("tiff", 0, "Graphics"         , "gfxfile.png"),
                    ("tga",  0, "Graphics"         , "gfxfile.png"),
                    ("ico",  0, "Graphics / Icon"  , "gfxfile.png"),
                    ("html", 0, "HTML"             , "htmlfile.png"),
                    ("htm",  0, "HTML"             , "htmlfile.png"),
                    ("iso",  0, "ISO image"        , "somefile.png"),
                    ("img",  0, "Floppy image"     , "somefile.png"),
                    ("pdf",  0, "Portable Document format"  , "somefile.png"),
                    ("bat",  0, "DOS batch file"   , "textfile.png"),
                    ("exe",  0, "DOS executable"   , "textfile.png"),
                    ("com",  0, "DOS executable"   , "textfile.png"),
                    ("dll",  0, "Windoze library"  , "textfile.png"),
                    ("ogg",  0, "Music / Ogg"      , "textfile.png"),
                    ("mp3",  0, "Music / MP3"      , "textfile.png"),
                    ("bak",  0, "Old version"      , "somefile.png"),
                  ]
default_extension_info = ("", 0, ""   , "somefile.png" )

# -----------------------------------------------------------------------
# create quick access dicts:

file_extensions = {}
for i in extensions_info:
  file_extensions[ i[0] ] = Bunch( extension=i[0], colorcode=i[1], imgurl=icons_base_url + i[3], text=i[2] )

file_extension_default = Bunch( extension=None,
                                colorcode=default_extension_info[1], 
                                imgurl=icons_base_url + default_extension_info[3],
                                text=default_extension_info[2] )

color_codes = {}
for cc in color_codes_info:
  b = Bunch( id=cc[0], color=cc[1], text=cc[2], openHTML=cc[3], closeHTML=cc[4] )
  color_codes[ cc[0] ] = b

folder_info = Bunch( extension=folder_info[0], 
                     colorcode=folder_info[2],
                     imgurl=icons_base_url + folder_info[3],
                     text=folder_info[1] )

# -----------------------------------------------------------------------


# read complete directory tree into a dict:

dirs = {}

def dirfunc( arg, dirname, content ):
  dirs[ dirname ] = content
  
os.path.walk( base_path, dirfunc, None )


# ---------------------------------

# output functions:

#    os.stat(path) -> (st_mode, st_ino, st_dev, st_nlink, st_uid, st_gid,
#                      st_size, st_atime, st_mtime, st_ctime)
#    Perform a stat system call on the given path.

def textInColor( text, color ):
  return "<font color='%s'>%s</font>" % ( color, text )

def imgTag( imgurl, opts="align=center" ):
  return "<img src='%s' %s>" % ( imgurl, opts )

def levelIndent( level ):
  return "&nbsp;"*4*level

def stringReverse( s ):
  l = list( s )
  l.reverse()
  return "".join( l )

def niceSizeText( i ):
  re1 = re.compile("(\d\d\d)")

  r      = stringReverse( str(i) )
  r_list = re1.split( r )
  while r_list.count('') > 0:
    r_list.remove('')

  if len(r) > (3*len(r_list)):
    rest = r[ 3*len(r_list): ]
    s = ".".join( r_list ) + "." + rest
  else:
    s = ".".join( r_list )
  return stringReverse( s )




def showDirEntry( dirname, level ):          # level is the depth of recursion
  splitted_dirname = os.path.split( dirname )
  fname = splitted_dirname[1]

  img = imgTag( folder_info.imgurl ) + "&nbsp;"

  color_info = color_codes[ folder_info.colorcode ]
  s = levelIndent( level )
  td1 = "<td valign=top>" + s  + img + color_info.openHTML + textInColor( fname, color_info.color )  + color_info.closeHTML + "</td>"
  td2 = "<td valign=top>" + "&nbsp;" + "</td>"
  td3 = "<td>&nbsp;</td>"
  print "<tr>%s%s%s</tr>" % ( td1, td2, td3 )



def showFileEntry( filename, level, showhref=0 ):        # level is the depth of recursion
  st = os.stat( filename )
  size  = st[ 6 ]
  atime = st[ 7 ]
  mtime = st[ 8 ]
  ctime = st[ 9 ]

  size = niceSizeText( size )

  if os.path.islink( filename ):
    showhref = 0

  splitted_filename = os.path.split( filename )
  fname = splitted_filename[1]
  fname_ext_list = fname.split(".")
  ext = ""
  if len(fname_ext_list) == 2:
    ext = fname_ext_list[ 1 ]

  ext_info   = file_extensions.get( ext, file_extension_default )
  color_code = ext_info.colorcode
  img        = imgTag( ext_info.imgurl ) + "&nbsp;"

  color_info  = color_codes[ color_code ]

  textToShow = fname
  if showhref:
    relpath = filename[ len(base_path): ]
    textToShow = "<a href='" + base_path +  relpath + "'>" + fname + "</a>"
  textToShow = textInColor( textToShow, color_info.color )

  s = levelIndent( level )
  td1 = "<td valign=top>" + s   + img + color_info.openHTML + textToShow + color_info.closeHTML + "</td>"
  td2 = "<td valign=top>" + "<i>"  + ext_info.text   + "</i>"    + "</td>"
  td3 = "<td valign=top align=right>%s</td>" % ( size )

  print "<tr>%s%s%s</tr>" % ( td1, td3, td2 )

# ---------------------------------

# scan the dirs hash:

def scanHash( complete_dir, level, showhref ):
  if dirs.has_key( complete_dir ):
    content = dirs[ complete_dir ]
    content.sort()
    # print "Dir '%s' with level '%d'." % ( complete_dir, level )
    showDirEntry( complete_dir, level )
    for c in content:
      scanHash( complete_dir + '/' + c, level+1, showhref )
  else:
    # it is a file...
    showFileEntry( complete_dir, level, showhref )
    # print "File '%s' with level '%d'." % ( complete_dir, level )

# -------------------------------------------------------------

print "<table cellspacing=5>"
#print "<tr>"
#for th in table_headers:
#  if type(th) == type( () ):
#    print "<th align=left width='%d'>%s</th>" % ( th[1], th[0] )
#  else:
#    print "<th align=left>%s</th>" % ( th )
#print "</tr>"

scanHash( base_path, 0, create_links )
print "</table>"

