Is it pythonic to have my own util library?

Paul Johnston paj at pajhome.org.uk
Sun Jan 19 17:47:31 EST 2003


Hi,

One thing I've noticed about my programming style is that whatever
language I use, I usually end up having a "paj's utility library" that
makes some common tasks one-liners.

Python's neat concise style takes away the need for a lot of them - for
example open(filename).read() is just perfect. But still I've got quite
a few functions - mostly for database access and template files. I've
attached the one I'm using for at the moment and would be interested in
comments.

Is this a good idea?
Is there some high-level database API I haven't found?
Are there better packages for doing templates?

I'd be interested in comments on the readability of
http://pajhome.org.uk/site/guest_src.html

Thanks,

Paul
http://pajhome.org.uk/
-------------- next part --------------
#--
# Paj's python utility library
#--
import re, string, time, MySQL, os

#--
# Template class
#
# This class let you use template files, where variables like $$VARIABLE are
# substituted, using a hash of data. An exception is raised if the variable is
# not defined.
#
# The templates can contain blocks deliminated by <$ block name $>...<$ end $>
# Newlines around the deliminators are removed. The main block is called ''
#--
class Template:  
  def __init__(self, filename):
    data = open(filename).read()
    regex = re.compile('\<\$ block (\w+) \$\>\n?(.*?)\n?\<\$ end \$\>\n?', 
                       re.DOTALL | re.MULTILINE | re.IGNORECASE)
    self.blocks = {}
    self.blocks[''] = regex.sub(self.found_block, data)
  
  def found_block(self, match):
    self.blocks[match.group(1)] = match.group(2)
    return ''
    
  def get_block(self, block, vars):
    self.vars = vars
    return re.sub('\$\$(\w+)', self.found_var, self.blocks[block])
 
  def found_var(self, match):
    return str(self.vars[str(match.group(1))])
    
#--
# Escape special characters in user input
# The resulting string will display like the original in HTML
# This string is now (hopefully) safe for HTML, SQL and email
# TBD: rewrite this so it only lets through known safe chars
#--
map = \
{
  "&":  "&",
  "'":  "’",
  '"':  """, 
  "<":  "<",
  ">":  ">",
  "\n": " ",
  "\r": " "
}
def escape_input(input):
  output = ''
  for char in input:
    if map.has_key(char):
      output = output + map[char]
    else:
      output = output + char      
  return output

#--
# Get a list of form fields safely into a hash
#--
def parse_fields(form, fields):
  data = {}
  for field in fields:
    if form.has_key(field):
      data[field] = escape_input(form[field].value)
    else:
      data[field] = ''
  return data
  
#--
# Do a database query; return cursor
#--
def db_query(db, query):
  try:
    result = db.query(query)
  except MySQL.error, err:
    raise MySQL.error, query + '\n' + err.args[0]
  return result

#--
# Do a SELECT query; return an array of hashes
#--
def select(db, query, fields):
  query = query % string.join(fields, ", ")
  output = []
  for row in db_query(db, query).fetchrows():
    hash = {}
    for i in range(0, len(fields)):
      if row[i] == None:
        hash[fields[i]] = ''
      else:
        hash[fields[i]] = str(row[i])
    output.append(hash)
  return output    

#--
# SELECT just one variable
#--
def select_one(db, query):
  return db_query(db, query).fetchrows()[0][0]

#--
# Do an UPDATE or INSERT
#--
def update(db, query, data):
  set_list = ''
  for field in data.keys():
    set_list = set_list + "%s='%s'," % (field, data[field])
  return db_query(db, query % set_list[:-1])

#--
# RFC 822 style date; for use in email Date: header
#--
def rfc822_date():
  fmt = '%a, %d %b %Y %H:%M:%S +0000'
  return time.strftime(fmt, time.gmtime(time.time()))

#--
# Send an email
#--
def sendmail(msg):
  sendmail = os.popen('/usr/sbin/sendmail -t', 'w')
  sendmail.write(msg)
  sendmail.close()


More information about the Python-list mailing list