"""Display a message.""" # meoWWW # Copyright 1999 G.J. Andruk # # This program 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. # # This program 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 this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. import config, os, sys, string, cgi, urllib, rfc822, mimetools, re from mimify import mime_decode_header from cStringIO import StringIO def dumphdr(article, hdr): try: hdrtxt = article.getheader(hdr) if hdrtxt: OF.write("%s: %s
%s" % (hdr, cgi.escape(hdrtxt), NL)) except: OF.write('darn %s' % sys.exc_info()[1]) def dumprefs(reflist): if 1: # set to 1 for normal refs, 0 for verbose. refcounter = 1 for ref in reflist: OF.write('[%d] ' % (scriptname, urllib.quote_plus(ref[1:-1]), refcounter)) refcounter = refcounter + 1 if refcounter > 2: OF.write(' <-newest') else: for ref in reflist: OF.write('%s ' % (scriptname, urllib.quote_plus(ref[1:-1]), cgi.escape(ref))) OF.write('
' + NL) def dumpgroups(nglist): comma = '' for group in nglist: group = string.strip(group) OF.write('%s %s' % (comma, scriptname, urllib.quote_plus(group), cgi.escape(group))) comma = ',' OF.write('
' + NL) def idrepl(match): """Doctor a news or nntp URL to point to ourselves.""" mg1 = match.group(1) mg2 = match.group(2) if '@' in mg2: if mg2[-3:] == '...': # outlook attrib goofiness mg2b = urllib.quote_plus(mg2[:-3]) else: mg2b = urllib.quote_plus(mg2) return ('' + mg1 + mg2 + '' + match.group(3)) else: return ('' + mg1 + mg2 + '' + match.group(3)) def dumpart(artlist, artitem=None, groupinfo=None): global wrotehead if raw: if not wrotehead: OF.write('Content-Type: text/plain' + NL + NL) wrotehead = 1 for line in artlist: OF.write(line + NL) else: if not wrotehead: OF.write('Content-Type: text/html' + NL + NL + '%s%s - article%s' % (cfg.doctype, config.name, cfg.body) + NL) OF.write('[%s]' % (scriptname, config.name)) if reqhash.has_key('group'): if groupinfo: if int(artitem) > int(groupinfo[2]): OF.write(' - ' '[Prev in Group] ' % (scriptname, reqhash['group'], artitem)) else: OF.write(' - [Prev in Group]') if int(artitem) < int(groupinfo[3]): OF.write(' ' '[Next in Group] ' % (scriptname, reqhash['group'], artitem)) else: OF.write(' [Next in Group]') OF.write('

%s

' %(scriptname, reqhash['group'], string.split(reqhash['group'], ',')[0])) wrotehead = 1 artfile = StringIO() artfile.write(string.join(artlist, '\n')) artfile.seek(0) del artlist article = mimetools.Message(artfile) hdrtxt = article.getheader('Subject') if hdrtxt: if artitem: OF.write('

%s: %s

%s' % (artitem, cgi.escape(mime_decode_header(hdrtxt)), NL)) else: OF.write('

%s

%s' % (cgi.escape(mime_decode_header(hdrtxt)), NL)) if artitem: linktext = 'g=%s+a=%s' % (reqhash['group'], artitem) else: linktext = reqhash['query'] OF.write('[Full Header] ' % (scriptname, linktext) + '[Plain Text] ' % (scriptname, linktext) + '- [Public Followup] ' % (scriptname, linktext) + '[Private Reply] ' % (scriptname, linktext) + '
' + NL ) for hdr in ('From', 'Reply-To'): hdrtxt = article.getheader(hdr) if hdrtxt: if (hdr == 'From' and article.getheader('Reply-To')): OF.write("%s: %s
%s" % (hdr, mime_decode_header(cgi.escape(hdrtxt)), NL)) else: replyto = rfc822.parseaddr(hdrtxt)[1] OF.write( '%s: %s
%s' % (cgi.escape(hdr), replyto, cgi.escape(mime_decode_header(hdrtxt)), NL)) hdrtxt = article.getheader('Newsgroups') if hdrtxt: OF.write('Newsgroups: ') dumpgroups(string.split(hdrtxt, ',')) dumphdr(article, 'Date') if 0: hdrtxt = article.getheader('Message-ID') if hdrtxt: OF.write("%s: %s
" % ('Message-ID', cgi.escape(hdrtxt))) hdrtxt = article.getheader('References') if hdrtxt: OF.write('References: ') dumprefs(string.split(hdrtxt)) hdrtxt = article.getheader('Followup-To') if hdrtxt: OF.write('Followup-To: ') if hdrtxt == 'poster': OF.write('poster
%s' % (replyto, NL)) else: dumpgroups(string.split(hdrtxt, ',')) for hdr in ('Organization', 'X-Meow'): dumphdr(article, hdr) hdrtxt = article.getheader('--Error--') if hdrtxt: OF.write(hdrtxt) bodytype = article.getheader('Content-Type') if bodytype: bodytype = string.lower(string.split(bodytype, ';')[0]) else: bodytype = 'text/plain' encoding = article.getencoding() article.rewindbody() if encoding in ('base64', 'quoted-printable', 'uuencode'): arttemp = StringIO() mimetools.decode(artfile, arttemp, encoding) arttemp.seek(0) artwork = arttemp else: artwork = artfile if 0: #cfg.render_html and bodytype == 'text/html': OF.write(artwork.read()) else: OF.write('
')
            htlink = re.compile('((?:telnet:|ftp:/|gopher:/'+
                                   '|mailto:|http:/).*?)([\s")]|>|$)', re.I)
            idlink = re.compile('(news:|nntp:)(.*?)([\s")]|>|$)', re.I)
            ngrepl = '\\1\\2\\3'
            incite = 0
            insig = 0
            while 1:
                line = artwork.readline()
                if not line:
                    break
                elif line [-2:] == NL:
                    line = line[:-2]
                elif line[-1] in NL:
                    line = line[:-1]
                line = re.sub(htlink, '\\1\\2',
                              cgi.escape(line))
                line = re.sub(idlink, idrepl, line)
                if line == '-- ':
                    OF.write('--' + NL)
                    insig = 1
                    OF.write('')
                else:
                    if (line and (line[0] in ':|' or line[0:4] == '>')):
                        if not incite:
                            OF.write('')
                            incite = 1
                    else:
                        if incite and not insig:
                            OF.write('')
                            incite = 0
                    OF.write(line + NL)
            if insig or incite:
                OF.write('')
            OF.write('
' + NL) OF=StringIO() cfg = config.config() scriptname = os.environ['SCRIPT_NAME'] NL = '\015\012' raw = 0 head = 0 donext = 0 dolast = 0 wrotehead = 0 reqinfo = string.split(urllib.unquote_plus(os.environ['QUERY_STRING'])) reqhash = {} for option in reqinfo: if option[0:2] == 'g=': reqhash['group'] = option[2:] elif option[0:2] == 'a=': reqhash['article'] = option[2:] elif option[0:2] == 'm=': reqhash['msgid'] = option[2:] elif option == 'n': donext = 1 elif option == 'l': dolast = 1 elif option == 'h': head = 1 elif option == 'r': raw = 1 if reqhash.has_key('group') and reqhash.has_key('article'): reqhash['query'] = 'g=%s+a=%s' % (reqhash['group'], reqhash['article']) elif reqhash.has_key('msgid'): reqhash['query'] = 'm=%s' % reqhash['msgid'] else: raise TypeError, 'Must supply Message-ID, or group and artnum.' rh = cfg.connect() try: if reqhash['query'][0] == 'm': if head: resp, artno, msgid, artlist = rh.head('<%s>' % reqhash['msgid']) else: resp, artno, msgid, artlist = rh.article('<%s>' % reqhash['msgid']) dumpart(artlist) else: groupctx = rh.group(string.split(reqhash['group'], ',')[0]) artsequence = string.split(reqhash['article'], '.') if len(artsequence) < 2 or raw: reqhash['article'] = rh.stat(reqhash['article'])[1] if donext: reqhash['article'] = rh.next()[1] elif dolast: reqhash['article'] = rh.last()[1] reqhash['query'] = ('g=%s+a=%s' % (reqhash['group'], reqhash['article'])) if head: resp, artno, msgid, artlist = rh.head(reqhash['article']) else: resp, artno, msgid, artlist = \ rh.article(reqhash['article']) dumpart(artlist, artitem=artno, groupinfo=groupctx) else: for artitem in artsequence: try: resp, artno, msgid, artlist = rh.article(artitem) dumpart(artlist, artitem) except: dumpart(['--Error--: (article %s unavailable)' % artitem], artitem) OF.write('
') if not raw: OF.write("" + NL) except: raise IOError, ("Cannot display article, server message was `%s'" % str(sys.exc_info()[1])) OF.seek(0) sys.stdout.write(OF.read()) OF.close() del OF rh.quit()