cgi help

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Wed Jun 1 15:01:27 CEST 2005


nephish a écrit :
> Hey there,
> i am trying to write an online application using the cgi module.
> what i want to do is have an html form display a drop-down list and
> have the values of that list be the lines of text written in a file.

Simplest, Q&D solution :
1/ open the file for reading
2/ print out the beginning of the html tags for the dropdown (hint:  in 
html, it's <input type="select">)
3/ for each line in the file, print out the html tags and the line
4/ print out the end of the html
5/ close the file

which gives (first try, Q&D, naive implementation, no error handling, etc:

f = open("myfile.txt")
print "<input type='select' name='my-drop-down-list'>"
for line in f:
   print "<option>%s</option>" %  line.strip()
print "</input>"
f.close()

Now there may be some conditions we want to handle: file doesnt exist or 
is not readable, file is empty, a line is empty, etc. A second try could 
be like:

try:
   f = open("myfile.txt")
except IOError, e:
   # TODO : handle error. in the meantime:
   print "could not open myfile.txt for reading : %s" % e
   sys.exit(1)
else:
   print "<input type='select' name='my-drop-down-list'>"
   for line in f:
     if line.strip():
       print "<option>%s</option>" %  line.strip()
print "</input>"
f.close()

Well... This does not handle all potential problems, and we begin to 
have useless repetitions (here the 'line.strip()' expression). We need 
to stop and think a little bit.

This snippet tries to do too many things at once: reading a file line by 
line, and printing the html for a select. Since we won't use selects for 
huge lists (for obvious usability reasons), we can assume that working 
with an in-memory list will be ok. So we could split this in two parts: 
one that read the file and returns a cleaned-up, ready to use list, and 
one that output the needed html:

# first part
try:
   f = open("myfile.txt")
except IOError, e:
   # TODO : handle error. in the meantime:
   print "could not open myfile.txt for reading : %s" % e
   sys.exit(1)
else:
   options = filter(None, [line.strip() for line in f])
   f.close()

   # second part:
   if options:
     print "<input type='select' name='my-drop-down-list'>"
     for line in options:
       print "<option>%s</option>" %  line
     print "</input>"
   else:
     # Err ? what should we do here ?
     print "<i>no selectable option here</i>"

Hmm... Better, but still not ok. We can already guess that both parts 
can be useful indepently of each other, in in other contexts. So why not 
making this a little be generic ?

def listFrom(openedFile):
   return  filter(None, [line.strip() for line in openedFile])

def printSelect(name, options):
   print "<input type='select' name='%s'>" % name
   for line in options:
     print "<option>%s</option>" %  line
   print "</input>"


def printSelectFromFile(name, path):
   try:
     f = open(path)
   except IOError, e:
     # TODO : handle error. in the meantime:
     print "could not open %s for reading : %s" % (path, e)
     sys.exit(1)
   else:
     options = listFrom(f)
     f.close()
     if options:
       printDropdownList(name, options)
     else:
       print "<i>no selectable option here</i>"

Well, this could of course be much more improved, but this will depend 
on stuffs specific to your application, so I'll leave it up to you...

> this would be updated almost every time the site is visited.
Err... Better take care of concurrent access...

> i have been sucessful in writing text to a file from an html form. but
> i need to access this so it can be selected.
> is there a way to do this? i have found limited info on how to really
> use the cgi module.  

AFAICT, there's nothing related to the cgi module in your problem.

HTH
Bruno



More information about the Python-list mailing list