#!/usr/bin/env python
#
# Copyright 2010 Wojciech 'KosciaK' Pietrzok
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# ----------------------------------------------------------------------
#
# Icons used:
# famfamfam's "Silk" icon set - http://www.famfamfam.com/lab/icons/silk/
#
__author__ = "Wojciech 'KosciaK' Pietrzok (kosciak@kosciak.net), Tommy MacWilliam (macwilliamt@gmail.com)"
__version__ = "0.4.3"
import sys
import os
import time
import locale
from optparse import OptionParser
locale.setlocale(locale.LC_ALL, '')
LANG, ENCODING = locale.getlocale()
DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
TABLE_HEADERS = {'en_GB': ('Name', 'Size', 'Last Modified'),
'pl_PL': ('Nazwa', 'Rozmiar', 'Czas modyfikacji')}
SCRIPT_WWW = 'http://code.google.com/p/kosciak-misc/wiki/DropboxIndex'
FILES_URL = 'http://dl.dropbox.com/u/69843/dropbox-index'
ICONS = (
'%s/icons/back.png' % FILES_URL,
'%s/icons/folder.png' % FILES_URL,
'%s/icons/file.png' % FILES_URL,
'%s/icons/image.png' % FILES_URL,
'%s/icons/video.png' % FILES_URL,
'%s/icons/music.png' % FILES_URL,
'%s/icons/archive.png' % FILES_URL,
'%s/icons/package.png' % FILES_URL,
'%s/icons/pdf.png' % FILES_URL,
'%s/icons/txt.png' % FILES_URL,
'%s/icons/markup.png' % FILES_URL,
'%s/icons/code.png' % FILES_URL,
'%s/icons/font.png' % FILES_URL,
'%s/icons/document.png' % FILES_URL,
'%s/icons/spreadsheet.png' % FILES_URL,
'%s/icons/presentation.png' % FILES_URL,
'%s/icons/application.png' % FILES_URL,
'%s/icons/plugin.png' % FILES_URL,
'%s/icons/iso.png' % FILES_URL,
)
FILE_TYPES = {
('gif', 'jpg', 'jpeg', 'png', 'bmp', 'tif', 'tiff', 'raw', 'img', 'ico', ): 'image',
('avi', 'ram', 'mpg', 'mpeg', 'mov', 'asf', 'wmv', 'asx', 'ogm', 'vob', '3gp', ): 'video',
('mp3', 'ogg', 'mpc', 'wav', 'wave', 'flac', 'shn', 'ape', 'mid', 'midi', 'wma', 'rm', 'aac', 'mka', ): 'music',
('tar', 'bz2', 'gz', 'arj', 'rar', 'zip', '7z', ): 'archive',
('deb', 'rpm', 'pkg', 'jar', 'war', 'ear', ): 'package',
('pdf', ): 'pdf',
('txt', ): 'txt',
('html', 'htm', 'xml', 'css', 'rss', 'yaml', 'php', 'php3', 'php4', 'php5', ): 'markup',
('js', 'py', 'pl', 'java', 'c', 'h', 'cpp', 'hpp', 'sql', ): 'code',
('ttf', 'otf', 'fnt', ): 'font',
('doc', 'rtf', 'odt', 'abw', 'docx', 'sxw', ): 'document',
('xls', 'ods', 'csv', 'sdc', 'xlsx', ): 'spreadsheet',
('ppt', 'odp', 'pptx', ): 'presentation',
('exe', 'msi', 'bin', 'dmg', ): 'application',
('xpi', ): 'plugin',
('iso', 'nrg', ): 'iso',
}
HTML_STYLE = '''
''' % ICONS
HTML_JAVASCRIPT = '''
''' % (FILES_URL, FILES_URL)
FAVICON = '' % FILES_URL
HTML_START = '''
%(PATH)s
%(FAVICON)s
%(HTML_STYLE)s
%(HTML_JAVASCRIPT)s
'''
HTML_HEADER = ''
HTML_TABLE_START = '''
| %s | %s | %s |
'''
HTML_BACK = '| .. | | |
'
HTML_DIR = '| %(file_name)s | | %(file_time)s |
\n'
HTML_FILE = '| %(file_name)s | %(file_size)s | %(file_time)s |
\n'
HTML_TABLE_END = '''
'''
HTML_DIR_INFO = '''
%(DIR_INFO)s
'''
HTML_END = '''
'''
def table_headers():
if LANG in TABLE_HEADERS:
return TABLE_HEADERS[LANG]
else:
return TABLE_HEADERS['en_GB']
def get_size(file):
size = os.path.getsize(file)
if size < 1000:
return '%s bytes' % size
kilo = size / 1024
if kilo < 1000:
return '%s KB' % round(float(size) / 1024, 1)
mega = kilo / 1024
return '%s MB' % round(float(kilo) / 1024, 1)
def get_filetype(file_name):
filetype = file_name.split('.')[-1].lower()
for keys, value in FILE_TYPES.items():
if filetype in keys:
return ' %s' % value
return ''
def html_render(path, back, dirs, files, template_file=None):
global PATH
PATH = os.path.basename(os.path.realpath(path))
dir_info = None
for file in files:
file_name = os.path.basename(file)
if 'dir-info' in file_name:
dir_info = open(file, 'r').read()
continue
index = open(os.path.join(path, 'index.html'), 'w')
if template_file:
global DIR_INFO
DIR_INFO = dir_info or ''
template = open(template_file, 'r').read()
head_start = template.find('') + 6
table_start = template.find('%(FILES)s')
index.write(template[0:head_start] % globals())
index.write(HTML_STYLE + HTML_JAVASCRIPT)
index.write(template[head_start:table_start] % globals())
else:
index.write(HTML_START % globals())
index.write(HTML_HEADER % PATH)
index.write(HTML_TABLE_START % table_headers())
if back:
index.write(HTML_BACK)
for file in dirs:
file_name = os.path.basename(file)
file_time = time.strftime(DATE_FORMAT, time.localtime(os.path.getmtime(file)))
file_time_sort = os.path.getmtime(file)
index.write(HTML_DIR % locals())
for file in files:
file_name = os.path.basename(file)
if 'dir-info' in file_name:
dir_info = open(file, 'r').read()
continue
file_type = get_filetype(file_name)
file_size = get_size(file)
file_size_sort = os.path.getsize(file)
file_time = time.strftime(DATE_FORMAT, time.localtime(os.path.getmtime(file)))
file_time_sort = os.path.getmtime(file)
index.write(HTML_FILE % locals())
now = time.strftime(DATE_FORMAT, time.localtime())
index.write(HTML_TABLE_END % (now, SCRIPT_WWW, __version__))
if template_file:
DIR_INFO = dir_info or ''
index.write(template[table_start+9:] % globals())
DIR_INFO = None
else:
index.write(HTML_DIR_INFO % {'DIR_INFO': dir_info or ''})
index.write(HTML_END)
def crawl(path, back=None, recursive=False, template_file=None):
if not os.path.exists(path):
print 'ERROR: Path %s does not exists' % path
return
if not os.path.isdir(path):
print 'ERROR: Path %s is not a directory' % path
return
# get contents of the directory
contents = [os.path.join(path, file) for file in os.listdir(path) if not file.endswith('index.html')]
# remove hidden files
# TODO: identify Windows hidden files
contents = [file for file in contents if not os.path.basename(file).startswith('.')]
# get only files
files = [file for file in contents if os.path.isfile(file)]
files.sort(key=str.lower)
# get only directories
if recursive:
dirs = [file for file in contents if os.path.isdir(file)]
dirs.sort(key=str.lower)
else:
dirs = [];
# render directory contents
html_render(path, back, dirs, files, template_file)
print 'Created index.html for %s' % os.path.realpath(path)
# crawl subdirectories
for dir in dirs:
crawl(dir, path, recursive, template_file)
def run():
epilog = '''ATTENTION:
Script will overwrite any existing index.html file(s)!
'''
parser = OptionParser(version='%prog ' + __version__,
usage="%prog [options] DIRECTORY",
epilog=epilog)
parser.add_option('-R', '--recursive',
action='store_true', default=False,
help='Include subdirectories [default: %default]')
parser.add_option('-T', '--template',
help='Use HTML file as template')
options, args = parser.parse_args()
if not args:
parser.print_help()
sys.exit()
crawl(path=args[0],
recursive=options.recursive,
template_file=options.template)
if __name__ == '__main__':
run()