Update of /cvsroot/tmda/tmda/contrib/cgi
In directory sc8-pr-cvs1:/tmp/cvs-serv23399
Added Files:
View.py
Log Message:
Code for viewing a pending e-mail on a web page. Navigation bars are provided.
--- NEW FILE ---
#!/usr/bin/env python
#
# Copyright (C) 2002 Gre7g Luterman <[EMAIL PROTECTED]>
#
# This file is part of TMDA.
#
# TMDA is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version. A copy of this license should
# be included in the file COPYING.
#
# TMDA is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with TMDA; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"View e-mail page for tmda-cgi."
import cgi
import email
import os
import pwd
import re
import string
import CgiUtil
from TMDA import Defaults
from TMDA import Util
# Pre-calc the regular expressions
TextType = re.compile("^text/")
MessageType = re.compile("^(message|multipart)/")
ImageType1 = re.compile("\.(GIF|JPG)$", re.I)
ImageType2 = re.compile("^image/")
MovieType1 = re.compile("\.(MOV|AVI|SWF)$", re.I)
MovieType2 = re.compile("^(video/|application/x-shockwave)")
PythonType1 = re.compile("\.(PY|PYC|PYO)$", re.I)
SoundType1 = re.compile("\.(AU|SND|MP3|WAV)$", re.I)
SoundType2 = re.compile("^audio/")
TextType1 = re.compile("\.(TXT)$", re.I)
ZipType1 = re.compile("\.(TGZ|ZIP|BZ|BZ2)$", re.I)
ZipType2 = re.compile("^application/zip")
def Attachment(Part):
"Generates some HTML to display an icon representing the attachment."
Filename = Part.get_filename("")
Icon = "exe"
if ImageType1.search(Filename): Icon = "image"
elif MovieType1.search(Filename): Icon = "movie"
elif PythonType1.search(Filename): Icon = "python"
elif SoundType1.search(Filename): Icon = "sound"
elif TextType1.search(Filename): Icon = "text"
elif ZipType1.search(Filename): Icon = "zip"
elif ImageType2.search(Part.get_type("text/plain")): Icon = "image"
elif MovieType2.search(Part.get_type("text/plain")): Icon = "movie"
elif SoundType2.search(Part.get_type("text/plain")): Icon = "sound"
elif ZipType2.search(Part.get_type("text/plain")): Icon = "zip"
return """<td>
<img src=display/%s.gif width=32 height=32><br>
%s<br>
(%s)
</td>
<td width="10">
</td>""" % (Icon, Filename, CgiUtil.Size(Part))
def Show():
"Show a login form in HTML."
# Check to make sure they're not trying to access anything other than email
if not re.compile("^\d+\.\d+\.msg$").search(PVars["MsgID"]):
raise IOError, "Bad e-mail filename"
# Change to the appropriate directory
os.chdir(os.path.join(Defaults.DATADIR, "pending"))
# Any subcommands?
if Form.has_key("subcmd"):
# Locate messages in pending dir
Msgs = CgiUtil.GetPendingList()
try:
MsgIdx = Msgs.index(PVars["MsgID"])
except: # Oops. Perhaps they released the message? Get the list!
print "Location: %s?cmd=list&SID=%s\n" % \
(os.environ["SCRIPT_NAME"], PVars.SID)
return
# first/prev/next/last subcommands
if Form["subcmd"].value == "first":
PVars["MsgID"] = Msgs[0]
PVars["Pager"] = 0
elif Form["subcmd"].value == "prev":
if MsgIdx > 0:
PVars["MsgID"] = Msgs[MsgIdx - 1]
PVars["Pager"] -= 1
elif Form["subcmd"].value == "next":
if MsgIdx < (len(Msgs) - 1):
PVars["MsgID"] = Msgs[MsgIdx + 1]
PVars["Pager"] += 1
elif Form["subcmd"].value == "last":
PVars["MsgID"] = Msgs[-1]
PVars["Pager"] = len(Msgs)
else:
# Read in e-mail
MsgObj = email.message_from_file(open(PVars["MsgID"], "r"))
ReturnPath = email.Utils.parseaddr(MsgObj.get('return-path'))[1]
# Check that we can access tmda-pending
if not os.access(Defaults.CGI_PATH_TO_PENDING, os.X_OK):
raise IOError, "Can't reach tmda-pending, check CGI_PATH_TO_PENDING"
# delete subcommand
if Form["subcmd"].value == "delete":
os.spawnl(os.P_WAIT, Defaults.CGI_PATH_TO_PENDING,
Defaults.CGI_PATH_TO_PENDING, "-qdb", Msgs[MsgIdx])
# release subcommand
elif Form["subcmd"].value == "release":
os.spawnl(os.P_WAIT, Defaults.CGI_PATH_TO_PENDING,
Defaults.CGI_PATH_TO_PENDING, "-qrb", Msgs[MsgIdx])
# white subcommand
elif Form["subcmd"].value == "white":
os.spawnl(os.P_WAIT, Defaults.CGI_PATH_TO_PENDING,
Defaults.CGI_PATH_TO_PENDING, "-qWb", Msgs[MsgIdx])
os.spawnl(os.P_WAIT, Defaults.CGI_PATH_TO_PENDING,
Defaults.CGI_PATH_TO_PENDING, "-qrb", Msgs[MsgIdx])
# black subcommand
elif Form["subcmd"].value == "black":
os.spawnl(os.P_WAIT, Defaults.CGI_PATH_TO_PENDING,
Defaults.CGI_PATH_TO_PENDING, "-qBb", Msgs[MsgIdx])
os.spawnl(os.P_WAIT, Defaults.CGI_PATH_TO_PENDING,
Defaults.CGI_PATH_TO_PENDING, "-qdb", Msgs[MsgIdx])
del Msgs[MsgIdx]
# So which message are we on now?
if len(Msgs) == 0: # Oops! None left!
print "Location: %s?cmd=list&SID=%s\n" % \
(os.environ["SCRIPT_NAME"], PVars.SID)
return
if MsgIdx >= len(Msgs): PVars["MsgID"] = Msgs[-1]
else: PVars["MsgID"] = Msgs[MsgIdx]
# Save session
PVars.Save()
# Use Javascript confirmation?
if Defaults.CGI_USE_JS_CONFIRM:
DeleteLink = "javascript:ConfirmDelete()"
BlackLink = "javascript:ConfirmBlacklist()"
else:
DeleteLink = "%s?cmd=view&subcmd=delete&SID=%s" % \
(os.environ["SCRIPT_NAME"], PVars.SID)
BlackLink = "%s?cmd=view&subcmd=black&SID=%s" % \
(os.environ["SCRIPT_NAME"], PVars.SID)
# Read in e-mail
MsgObj = email.message_from_file(open(PVars["MsgID"], "r"))
if PVars["Headers"] == "all":
# Generate all headers
MsgHTML = """<a href="%s?cmd=view&headers=short&SID=%s"><img
src="display/shorthead.gif" width="100" height="65" align="right" border="0"
alt="Show Short Headers"></a><pre>""" % (os.environ["SCRIPT_NAME"], PVars.SID)
for Line in string.split(CgiUtil.Escape(MsgObj.as_string()), "\n"):
if Line == "": break
MsgHTML += Line + "\n"
MsgHTML += "</pre>"
else:
# Generate short headers
MsgHTML = """<a href="%s?cmd=view&headers=all&SID=%s"><img
src="display/allhead.gif" width="100" height="65" align="right" border="0"
alt="Show All Headers"></a>
<table class="Headers" border="0" cellspacing="0" cellpadding="0">
<tr>
<th>From:</th>
<td width="5">
<td>%s</td>
</tr>
<tr>
<th>To:</th>
<td></td>
<td>%s</td>
</tr>
<tr>
<th>Subject:</th>
<td></td>
<td>%s</td>
</tr>
<tr>
<th>Date:</th>
<td></td>
<td>%s</td>
</tr>
""" % (os.environ["SCRIPT_NAME"], PVars.SID, CgiUtil.Escape(MsgObj["from"]),
CgiUtil.Escape(MsgObj["to"]), CgiUtil.Escape(MsgObj["subject"]),
CgiUtil.Escape(MsgObj["date"]))
if MsgObj.get("cc"):
MsgHTML += """<th>CC:</th>
<td></td>
<td>%s</td>
""" % CgiUtil.Escape(MsgObj["cc"])
MsgHTML += "</table><p>"
# Go through each part and generate HTML
TextParts = 0
Attachments = ""
for Part in MsgObj.walk():
Type = Part.get_type("text/plain")
# Display the easily display-able parts
if TextType.search(Type):
TextParts += 1
if TextParts > 1: MsgHTML += "<hr class=PartDiv>"
if Type == "text/plain":
MsgHTML += "<span class=EmailText>%s</span>" % \
string.replace(CgiUtil.Escape(string.strip(Part.get_payload(decode=1))),
"\n", " <br>")
else:
MsgHTML += Part.get_payload(decode=1)
# Don't show anything if the part contains other parts
# (those parts will be recursed seperately)
elif not MessageType.search(Type):
# Create an icon to show other attachments
Attachments += Attachment(Part)
# Show any attachments at the bottom of the email
if Attachments != "":
TextParts += 1
if TextParts > 1: MsgHTML += "<hr class=PartDiv>"
MsgHTML += """<table class=Attachments>
<tr>
%s
</tr>
</table>
""" % Attachments
# Any extra icons?
Columns = 7
ExtraIcon1 = ""
ExtraIcon2 = ""
if Defaults.PENDING_BLACKLIST_APPEND:
Columns += 1
if Defaults.PENDING_WHITELIST_APPEND:
Columns += 1
ColWidth = "%d%%" % int(100 / Columns)
if Defaults.PENDING_BLACKLIST_APPEND:
ExtraIcon1 = """<td width="%s"><a href="%s"><img alt="Blacklist & Delete"
src="display/black.gif" width="38" height="42" border="0"></a></td>
""" % (ColWidth, BlackLink)
if Defaults.PENDING_WHITELIST_APPEND:
ExtraIcon2 = """<td width="%s"><a href="%s?cmd=view&subcmd=white&SID=%s"><img
alt="Whitelist & Release" src="display/white.gif" width="40" height="42"
border="0"></a></td>
""" % (ColWidth, os.environ["SCRIPT_NAME"], PVars.SID)
# Precalculate the navigation bar (since we'll use it twice)
NavBarHTML = """ <tr align="center" class="NavBar">
<td width="%s"><a href="%s?cmd=view&subcmd=first&SID=%s"><img alt="First"
src="display/first.gif" width="24" height="42" border="0"></a></td>
<td width="%s"><a href="%s?cmd=view&subcmd=prev&SID=%s"><img alt="Prev"
src="display/prev.gif" width="21" height="42" border="0"></a></td>
<td width="%s"><a href="%s"><img alt="Delete" src="display/kill.gif"
width="30" height="42" border="0"></a></td>%s
<td width="%s"><a href="%s?cmd=list&SID=%s"><img alt="Entire List"
src="display/all.gif" width="45" height="42" border="0"></a></td>
<td width="%s"><a href="%s?cmd=view&subcmd=release&msgid=%s&SID=%s"><img
alt="Release"
src="display/accept.gif" width="38" height="42" border="0"></a></td>%s
<td width="%s"><a href="%s?cmd=view&subcmd=next&SID=%s"><img alt="Next"
src="display/next.gif" width="21" height="42" border="0"></a></td>
<td width="%s"><a href="%s?cmd=view&subcmd=last&SID=%s"><img alt="Last"
src="display/last.gif" width="24" height="42" border="0"></a></td>
</tr>""" % (ColWidth, os.environ["SCRIPT_NAME"], PVars.SID, ColWidth,
os.environ["SCRIPT_NAME"], PVars.SID, ColWidth, DeleteLink, ExtraIcon1,
ColWidth, os.environ["SCRIPT_NAME"], PVars.SID, ColWidth,
os.environ["SCRIPT_NAME"], PVars["MsgID"], PVars.SID, ExtraIcon2, ColWidth,
os.environ["SCRIPT_NAME"], PVars.SID, ColWidth, os.environ["SCRIPT_NAME"],
PVars.SID)
# Display HTML page with email included.
print """Content-type: text/html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>View E-mail</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link href="display/styles.css" rel="stylesheet" type="text/css">
</head>
<body class="ViewPage">
<table>
%s
<tr>
<td colspan="%d" class="Email">
<hr class=NavDiv>
%s
<hr class=NavDiv>
</td>
</tr>
%s
</table>""" % (NavBarHTML, Columns, MsgHTML, NavBarHTML)
# Javascript confirmation for delete and blacklist?
if Defaults.CGI_USE_JS_CONFIRM:
print """<script>
function ConfirmDelete()
{
if (confirm("Permanently delete this pending message?\\nAny confirmation that
follows will fail."))
document.location.href = "%s?cmd=view&subcmd=delete&msgid=%s&SID=%s"
}
function ConfirmBlacklist()
{
if (confirm("Blacklist sender and permanently delete this pending message?"))
document.location.href = "%s?cmd=view&subcmd=black&msgid=%s&SID=%s"
}
</script>""" % (os.environ["SCRIPT_NAME"], PVars["MsgID"], PVars.SID,
os.environ["SCRIPT_NAME"], PVars["MsgID"], PVars.SID)
print """</body>
</html>"""
_______________________________________
tmda-cvs mailing list
http://tmda.net/lists/listinfo/tmda-cvs