2
\$\begingroup\$

This is a Python script I made to create a HTML page listing the source files in the current directory. The script creates a syntax highlighted preview of the files and lists some basic attributes.

I would like to know if this is the best method to generate the HTML code? Is there a web development library that would be more efficient for this task?

What are some ways that I could improve my webpage design?

# -*- coding: utf-8 -*-
import pygments
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import HtmlFormatter
from pygments.lexers import guess_lexer, get_lexer_for_filename
from os import listdir, mkdir
from os.path import isfile, join, getsize, getctime, isdir, dirname, abspath
from time import ctime
import glob
from math import ceil

# configuration
mypath = "."
maxlines = 30
items_per_page = 10.0
base_path = dirname(abspath(__file__))+"/"
files_to_ignore = ["pgp", "der", "crt", "asc", "key"]

if isdir("pastebin/") == False:
    mkdir("pastebin/")

onlyfiles = [ f for f in glob.glob(mypath+"/*.*") if isfile(join(mypath,f)) ]
template = """
<!DOCTYPE html>

<style>
    .main-page {
        background-color:#C0C0C0;
    }
    .list-item {
        width:90%;
        margin-top:10px;
        margin-bottom:10px;
        margin-right:5%;
        margin-left:5%;
        background-color:white;
        box-shadow: 5px 5px 5px #888888;
    }
    h3 {
        margin-top:10px;
        text-align:center;
    }
    .source {
        margin-right:10px;
        margin-left:10px;
        margin-top:10px;
        margin-bottom:10px;
        overflow:hidden;
    }
    footer {
        bottom: 0;
        position: fixed;
        text-align:center;
        width: 100%;
        margin-top:10px;
        background-color:white;
    }

</style>
<body class="main-page">
"""
valid_files = []
for name in onlyfiles:
    if name.split(".")[1:] in files_to_ignore:
        pass
    else:
        try:
            get_lexer_for_filename(name)
            valid_files.append(name)
        except pygments.util.ClassNotFound:
            pass

page_links = ""
for n in range(1, int(ceil(len(valid_files)/items_per_page))):
    page_links+="""<a href="page%d.html"> %d </a>"""%(n, n)
count=0
page_count=1
output=template
for name in valid_files:
    count+=1.0

    name=name.replace("./", "")
    code = "".join(open(name, "rb").readlines()[:maxlines])
    lexer = get_lexer_for_filename(name)
    formatter = HtmlFormatter(linenos=False, cssclass="source", encoding="utf-8")
    result = highlight(code, lexer, formatter)
    temp="""<div class="list-item">"""
    temp+="<style> ccs-color-codes  </style>"
    temp+="""<h3><a href="file-path">file-name </a></h3><div class="info">"""
    temp+=""" Created on: <b>date-created </b>"""
    temp+="""Size: <b>file-size </b>""" 
    temp+="""</div><hr>result</div>"""

    temp=temp.replace("ccs-color-codes", HtmlFormatter().get_style_defs('.source'))
    temp=temp.replace("file-name", name)
    temp=temp.replace("file-path", base_path+name)
    temp=temp.replace("file-size", str(getsize(name)))
    temp=temp.replace("date-created", ctime(getctime(name)))
    temp=temp.replace("result", result)
    output+=temp+"\n"

    if int(count) == int(items_per_page):
        count=0
        output+="""<footer><span id="footer">%s</span></footer>"""%(page_links)
        output+="</body>"
        open("pastebin/page%d.html"%(page_count), "w").write(output)
        page_count+=1
\$\endgroup\$
3
\$\begingroup\$

There are a ton of good template rendering libraries out there, but I'd leave it to you to figure out if they are better suited to your needs than hand rolled code.

Assuming you still want to write this yourself, I'd look for ways to make the code more completely data driven and also to make it more readable.

On the data driven side, you might want save your design as an html file. That way you can use whatever styling or graphic layout tools you want to produce the layout. You merely need to leave template placeholders where you want the data to go and apply the substitutions. Django's templating system offers a great example of what you'd expect: vanilla html data with placeholders where the data's gonna go.

Going data driven will reduce a ton of the code here (since so much of it is just string assembly). You can do some nice syntactic tricks to clean up things like writing html tags, for example

 tag = lambda t, c : "<%s>%s></%s>" % (t,c,t)

 tag('footer','footer goes here')
 >  <footer>footer goes here</footer>

And you you could also use a context manager for tag nesting (example here) to keep things neat

Lastly, use string.Template to allow for keyword or dictionary based replacement you can do things like

header = Template("<header><span font=$font>$text</span></header")
header.subsitute(font='sans-serif',text='hello world')

that would make it easier to clean up the series of temp = temp.replace... lines. Python is a great language for this sort of thing - it should be easy to cut this down by half or more with built in tools.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.