refurbished css for webpage generator
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
#!/usr/bin/env python
|
||||
# coding=utf-8
|
||||
''' A script that creates an index for a folder.
|
||||
''' A script that creates an index for a folder.
|
||||
'''
|
||||
|
||||
import os,sys,time
|
||||
import urllib
|
||||
VERSION="20160116"
|
||||
IMAGE_EXTENSIONS=['png','gif','jpg','jpeg','tif','tiff']
|
||||
|
||||
VERSION = "20181206"
|
||||
IMAGE_EXTENSIONS = ['png', 'gif', 'jpg', 'jpeg', 'tif', 'tiff']
|
||||
|
||||
def setup():
|
||||
''' Setup the command line options '''
|
||||
from argparse import ArgumentParser
|
||||
from argparse import ArgumentParser
|
||||
parser=ArgumentParser()
|
||||
parser.add_argument("-f",action="store_true",dest="overwrite",default=False,
|
||||
help="Overwrite existing index file.")
|
||||
@@ -27,11 +28,12 @@ def setup():
|
||||
parser.add_argument("--version",action='version', version=VERSION)
|
||||
parser.add_argument("path",type=str,action="store",default=os.path.abspath('.'),nargs='?',
|
||||
help="Root path of the index")
|
||||
options=parser.parse_args()
|
||||
options.path=os.path.abspath(options.path)
|
||||
if options.title==None:
|
||||
options.title=os.path.basename(options.path)
|
||||
return options
|
||||
|
||||
options = parser.parse_args()
|
||||
options.path = os.path.abspath(options.path)
|
||||
if options.title == None:
|
||||
options.title = os.path.basename(options.path)
|
||||
return options
|
||||
|
||||
def setup2HTML(opts):
|
||||
return '<meta name="SimpleWebPageSetup" content="%s"/>'%";".join([
|
||||
@@ -42,18 +44,18 @@ def setup2HTML(opts):
|
||||
])
|
||||
|
||||
def HTML2setup(opts):
|
||||
f=open(os.path.join(opts.path,opts.filename), 'rt')
|
||||
try:
|
||||
f = open(os.path.join(opts.path,opts.filename), 'rt')
|
||||
try:
|
||||
for l in f.readlines():
|
||||
if l.find('name="SimpleWebPageSetup"')>-1:
|
||||
content=l[l.find('name="SimpleWebPageSetup"'):]
|
||||
if l.find('name="SimpleWebPageSetup"') > -1:
|
||||
content = l[l.find('name="SimpleWebPageSetup"'):]
|
||||
for s in content.split('"')[3].split(";"):
|
||||
(k,v)=s.split('=',1)
|
||||
if k=='hidden': opts.hidden=v=="True"
|
||||
if k=='parent': opts.parent=v=="True"
|
||||
if k=='title': opts.title=urllib.unquote(v)
|
||||
if k=='images': opts.images=v=="True"
|
||||
print("Reading options from existing "+opts.filename)
|
||||
(k,v) = s.split('=',1)
|
||||
if k == 'hidden': opts.hidden = v == "True"
|
||||
if k == 'parent': opts.parent = v == "True"
|
||||
if k == 'title': opts.title = urllib.unquote(v)
|
||||
if k == 'images': opts.images = v == "True"
|
||||
print("Reading options from existing " + opts.filename)
|
||||
break
|
||||
except:
|
||||
pass
|
||||
@@ -65,70 +67,133 @@ def generate_index(opts):
|
||||
if not opts.overwrite:
|
||||
print(opts.filename+" exists")
|
||||
sys.exit(1)
|
||||
opts=HTML2setup(opts)
|
||||
opts = HTML2setup(opts)
|
||||
files = [ f for f in files if f != opts.filename]
|
||||
if not opts.hidden:
|
||||
files = [ f for f in files if not f.startswith(".")]
|
||||
dirs = [ d for d in dirs if not d.startswith(".")]
|
||||
f=open(os.path.join(path,opts.filename),'wt')
|
||||
f = open(os.path.join(path,opts.filename),'wt')
|
||||
dirs.sort()
|
||||
files.sort()
|
||||
f.write(get_header(opts))
|
||||
if opts.parent:
|
||||
f.write(get_pathlink(path,'..'))
|
||||
f.write(get_pathlink(path, '..'))
|
||||
for di in dirs:
|
||||
f.write(get_pathlink(path,di))
|
||||
f.write(get_pathlink(path, di))
|
||||
for fi in files:
|
||||
f.write(get_filelink(path,fi,opts.images))
|
||||
f.write(get_filelink(path, fi, opts.images))
|
||||
f.write(get_footer())
|
||||
f.close()
|
||||
return
|
||||
|
||||
def get_filelink(path,fname,images=False):
|
||||
if os.path.islink(os.path.join(path,fname)) and not os.path.exists(os.path.join(path,fname)):
|
||||
(fsize,fsstr,fsstrb,fdstr)=(0,"NA","NA","NA")
|
||||
if os.path.islink(os.path.join(path, fname)) and not os.path.exists(os.path.join(path, fname)):
|
||||
(fsize, fsstr, fsstrb, fdstr)=(0, "NA", "NA", "NA")
|
||||
else:
|
||||
fsize=os.path.getsize(os.path.join(path,fname))
|
||||
fsstr=sizeof(fsize)
|
||||
fsstrb=str(fsize)
|
||||
fdate=time.localtime(os.path.getmtime(os.path.join(path,fname)))
|
||||
fdstr=time.strftime("%Y/%m/%d %H:%M:%S",fdate)
|
||||
fsize = os.path.getsize(os.path.join(path, fname))
|
||||
fsstr = sizeof(fsize)
|
||||
fsstrb = str(fsize)
|
||||
fdate = time.localtime(os.path.getmtime(os.path.join(path, fname)))
|
||||
fdstr = time.strftime("%Y/%m/%d %H:%M:%S", fdate)
|
||||
if images and is_imagefile(fname):
|
||||
fname_str=get_imagestr(fname)
|
||||
fname_str = get_imagestr(fname)
|
||||
else:
|
||||
fname_str=fname
|
||||
return '<tr><td><a href="'+urllib.quote(fname)+'">'+fname_str+'</a><td class="right">'+fsstr+'</td><td class="right bytes">'+fsstrb+'</td><td class="right">'+fdstr+'</td></tr>\n'
|
||||
fname_str = fname
|
||||
return '<tr><td><a class="link_file" href="%s">%s</a><td class="right">%s</td><td class="right bytes">%s</td><td class="right">%s</td></tr>\n'%(
|
||||
urllib.quote(fname),
|
||||
fname_str,
|
||||
fsstr,
|
||||
fsstrb,
|
||||
fdstr
|
||||
)
|
||||
|
||||
def get_imagestr(fname):
|
||||
return '<img src="'+urllib.quote(fname)+'" title="'+fname+'"/>'
|
||||
return '<img src="%s" title="%s"/>'%(
|
||||
urllib.quote(fname),
|
||||
fname
|
||||
)
|
||||
|
||||
def get_pathlink(path,dname):
|
||||
fdate=time.localtime(os.path.getmtime(os.path.join(path,dname)))
|
||||
fdstr=time.strftime("%Y/%m/%d %H:%M:%S",fdate)
|
||||
return '<tr><td><a href="'+urllib.quote(dname)+'">'+dname+'</a><td class="right">[DIR]</td><td class="right bytes">0</td><td class="right">'+fdstr+'</td></tr>\n'
|
||||
fdate = time.localtime(os.path.getmtime(os.path.join(path, dname)))
|
||||
fdstr = time.strftime("%Y/%m/%d %H:%M:%S", fdate)
|
||||
return '<tr><td><a class="link_dir" href="%s">↳ %s/</a><td class="right">[DIR]</td><td class="right bytes">0</td><td class="right">%s</td></tr>\n'%(
|
||||
urllib.quote(dname),
|
||||
dname,
|
||||
fdstr
|
||||
)
|
||||
|
||||
def get_header(opts):
|
||||
header='''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="generator" content="SimpleWebPage '''+VERSION+'''" />
|
||||
'''+setup2HTML(opts)+'''
|
||||
<title>Index of '''+opts.title+'''</title>
|
||||
<meta name="generator" content="SimpleWebPage ''' + VERSION + '''" />
|
||||
''' + setup2HTML(opts) + '''
|
||||
<title>''' + opts.title + '''</title>
|
||||
<style>
|
||||
* {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
body {
|
||||
font-family: monospace;
|
||||
color: #222;
|
||||
font: 14px monospace;
|
||||
padding: 20px;
|
||||
background: #CCC;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
padding: 20px 0 12px 0;
|
||||
margin: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
.container {
|
||||
box-shadow: 0 5px 10px -5px rgba(0,0,0,0.5);
|
||||
position: relative;
|
||||
background: #eee;
|
||||
}
|
||||
table {
|
||||
background-color: gray;
|
||||
background-color: #F3F3F3;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 15px 0;
|
||||
}
|
||||
td, th {
|
||||
text-align: left;
|
||||
background-color: lightgray;
|
||||
padding: 0.5ex;
|
||||
th {
|
||||
background-color: #EB6000;
|
||||
color: #FFF;
|
||||
cursor: pointer;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
td {
|
||||
padding-right: 5px;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
td a {
|
||||
color: #EB6000;
|
||||
display: block;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
th a {
|
||||
padding-left: 0
|
||||
}
|
||||
td:first-of-type a {
|
||||
padding-left: 5px;
|
||||
}
|
||||
th:first-of-type {
|
||||
padding-left: 5px;
|
||||
}
|
||||
tr:nth-of-type(odd) {
|
||||
background-color: #DDD;
|
||||
}
|
||||
tr:hover td {
|
||||
background-color:#BBB;
|
||||
}
|
||||
tr:hover td a {
|
||||
color: #222;
|
||||
}
|
||||
th { cursor: hand; }
|
||||
th:a { text-decoration: none; }
|
||||
.right {
|
||||
text-align: right;
|
||||
}
|
||||
@@ -180,7 +245,7 @@ function ts_makeSortable(t) {
|
||||
}
|
||||
}
|
||||
if (!firstRow) return;
|
||||
|
||||
|
||||
// We have a first row: assume it's the header, and make its contents clickable links
|
||||
for (var i=0;i<firstRow.cells.length;i++) {
|
||||
var cell = firstRow.cells[i];
|
||||
@@ -199,7 +264,7 @@ function ts_getInnerText(el) {
|
||||
if (typeof el == "undefined") { return el };
|
||||
if (el.innerText) return el.innerText; //Not needed but it is faster
|
||||
var str = "";
|
||||
|
||||
|
||||
var cs = el.childNodes;
|
||||
var l = cs.length;
|
||||
for (var i = 0; i < l; i++) {
|
||||
@@ -236,7 +301,7 @@ function ts_resortTable(lnk, clid) {
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (itm == "") return;
|
||||
if (itm == "") return;
|
||||
sortfn = ts_sort_caseinsensitive;
|
||||
if (itm.match(/^\d\d[\/\.-][a-zA-z][a-zA-Z][a-zA-Z][\/\.-]\d\d\d\d$/)) sortfn = ts_sort_date;
|
||||
if (itm.match(/^\d\d[\/\.-]\d\d[\/\.-]\d\d\d{2}?$/)) sortfn = ts_sort_date;
|
||||
@@ -246,19 +311,19 @@ function ts_resortTable(lnk, clid) {
|
||||
var firstRow = new Array();
|
||||
var newRows = new Array();
|
||||
for (k=0;k<t.tBodies.length;k++) {
|
||||
for (i=0;i<t.tBodies[k].rows[0].length;i++) {
|
||||
firstRow[i] = t.tBodies[k].rows[0][i];
|
||||
for (i=0;i<t.tBodies[k].rows[0].length;i++) {
|
||||
firstRow[i] = t.tBodies[k].rows[0][i];
|
||||
}
|
||||
}
|
||||
for (k=0;k<t.tBodies.length;k++) {
|
||||
if (!thead) {
|
||||
// Skip the first row
|
||||
for (j=1;j<t.tBodies[k].rows.length;j++) {
|
||||
for (j=1;j<t.tBodies[k].rows.length;j++) {
|
||||
newRows[j-1] = t.tBodies[k].rows[j];
|
||||
}
|
||||
} else {
|
||||
// Do NOT skip the first row
|
||||
for (j=0;j<t.tBodies[k].rows.length;j++) {
|
||||
for (j=0;j<t.tBodies[k].rows.length;j++) {
|
||||
newRows[j] = t.tBodies[k].rows[j];
|
||||
}
|
||||
}
|
||||
@@ -271,17 +336,17 @@ function ts_resortTable(lnk, clid) {
|
||||
} else {
|
||||
ARROW = ' ↓';
|
||||
span.setAttribute('sortdir','down');
|
||||
}
|
||||
}
|
||||
// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
|
||||
// don't do sortbottom rows
|
||||
for (i=0; i<newRows.length; i++) {
|
||||
for (i=0; i<newRows.length; i++) {
|
||||
if (!newRows[i].className || (newRows[i].className && (newRows[i].className.indexOf('sortbottom') == -1))) {
|
||||
t.tBodies[0].appendChild(newRows[i]);
|
||||
}
|
||||
}
|
||||
// do sortbottom rows only
|
||||
for (i=0; i<newRows.length; i++) {
|
||||
if (newRows[i].className && (newRows[i].className.indexOf('sortbottom') != -1))
|
||||
if (newRows[i].className && (newRows[i].className.indexOf('sortbottom') != -1))
|
||||
t.tBodies[0].appendChild(newRows[i]);
|
||||
}
|
||||
// Delete any other arrows there may be showing
|
||||
@@ -292,7 +357,7 @@ function ts_resortTable(lnk, clid) {
|
||||
allspans[ci].innerHTML = ' ↕';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
span.innerHTML = ARROW;
|
||||
alternate(t);
|
||||
}
|
||||
@@ -307,7 +372,7 @@ function getParent(el, pTagName) {
|
||||
}
|
||||
}
|
||||
|
||||
function sort_date(date) {
|
||||
function sort_date(date) {
|
||||
// y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
|
||||
dt = "00000000";
|
||||
if (date.length == 11) {
|
||||
@@ -340,10 +405,10 @@ function sort_date(date) {
|
||||
}
|
||||
} else if (date.length == 8) {
|
||||
yr = date.substr(6,2);
|
||||
if (parseInt(yr) < 50) {
|
||||
yr = '20'+yr;
|
||||
} else {
|
||||
yr = '19'+yr;
|
||||
if (parseInt(yr) < 50) {
|
||||
yr = '20'+yr;
|
||||
} else {
|
||||
yr = '19'+yr;
|
||||
}
|
||||
if (europeandate == true) {
|
||||
dt = yr+date.substr(3,2)+date.substr(0,2);
|
||||
@@ -359,11 +424,11 @@ function sort_date(date) {
|
||||
function ts_sort_date(a,b) {
|
||||
dt1 = sort_date(ts_getInnerText(a.cells[SORT_COLUMN_INDEX]));
|
||||
dt2 = sort_date(ts_getInnerText(b.cells[SORT_COLUMN_INDEX]));
|
||||
|
||||
|
||||
if (dt1==dt2) {
|
||||
return 0;
|
||||
}
|
||||
if (dt1<dt2) {
|
||||
if (dt1<dt2) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
@@ -453,23 +518,23 @@ function alternate(table) {
|
||||
tableRows[j].className += " odd";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Index of '''+opts.title+'''</h1>
|
||||
<div class="container">
|
||||
<h1>''' + opts.title + '''</h1>
|
||||
<table class="sortable" id="fileList"><thead><tr><th>Name</th><th class="right">Size</th><th class="right">Size B</th><th class="right">Modified</th></tr></thead><tbody>
|
||||
'''
|
||||
return header
|
||||
|
||||
def get_footer():
|
||||
footer='''</tbody></table>
|
||||
return '''</tbody></table></div>
|
||||
</body></html>'''
|
||||
return footer
|
||||
|
||||
def is_imagefile(fname):
|
||||
for ext in IMAGE_EXTENSIONS:
|
||||
@@ -484,6 +549,7 @@ def sizeof(num):
|
||||
return "%d %s" % (num, x)
|
||||
return "%3.1f %s" % (num, x)
|
||||
num /= 1024.0
|
||||
|
||||
opts=setup()
|
||||
generate_index(opts)
|
||||
|
||||
if __name__ == "__main__":
|
||||
opts = setup()
|
||||
generate_index(opts)
|
||||
|
||||
Reference in New Issue
Block a user