# # thread_cgi.py - Thread CGI methods. # Copyright (c) 2005 shinGETsu Project. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # $Id: thread_cgi.py,v 1.25 2005/08/12 06:43:11 fuktommy Exp $ # import cgi import mimetypes import re import config import gateway from cache import * __version__ = "$Revision: 1.25 $" class CGI(gateway.CGI): """Class for /thread.cgi.""" appli_type = "thread" def run(self): path = self.path_info() if (path != "") and (path.find("/") < 0): self.print_thread(path) return found = re.search(r"^(thread_[0-9A-F]+)/([0-9a-f]{32})/(\d+)\.(.*)", path) if found: (datfile, stamp, id, suffix) = found.groups() self.print_attach(datfile, stamp, id, suffix) return form = cgi.FieldStorage(environ=self.environ, fp=self.stdin) if form.getfirst("cmd", "") == "post" and \ form.getfirst("file", "").startswith("thread_") and \ self.environ["REQUEST_METHOD"] == "POST": id = self.do_post(path, form) if not id: return datfile = form.getfirst("file", "") title = self.str_encode(self.file_decode(datfile)) self.print302(self.thread_cgi + self.sep + title + "#r" + id) return self.print404() def print_thread(self, path): cache = Cache(self.file_encode("thread", path)) if cache.exists(): pass elif self.check_get_cache(): self.get_cache(cache) else: self.print404(cache) return record = cache.load_body() self.header(path) self.stdout.write( '
\n' + '

\n' + ' \n' + ' \n' % cache.datfile) if record: self.stdout.write( ' %s%s\n' % (self.res_anchor(record[-1].id[:8]), self.message["last_article"])) self.stdout.write('

\n
\n') for num, rec in enumerate(record): self.print_record(cache, num, rec) self.print_form(cache) self.remove_file_form(cache) self.footer() def print_record(self, cache, num, rec): num = num + 1 stamp = self.localtime(rec["stamp"]) if ("name" in rec) and (rec["name"] != ""): name = rec["name"] else: name = self.message["anonymous"] if ("mail" in rec) and (rec["mail"] != ""): mail = "\n [" + rec["mail"] + "]" else: mail = "" if "body" in rec: body = rec["body"] else: body = "" body = self.html_format(body) if "suffix" in rec: suffix = rec["suffix"] else: suffix = "" attach = "" if "attach" in rec: attach_file = rec.attach_path() attach_size = int(rec.attach_size(attach_file) / 1024) attach = ' ' + \ rec["stamp"] + '.' + suffix + '' + \ " (" + str(attach_size) + self.message["kb"] + ")\n" sign = "" if "pubkey" in rec: sign = ' %s' % \ (rec["target"], rec["pubkey"]) remove = "" if ("remove_id" in rec) and ("remove_stamp" in rec): remove = ('[[%s: %s%s]]
\n') % \ (self.message["remove"], self.res_anchor(rec["remove_id"][:8]), rec["remove_id"][:8]) self.stdout.write( '
\n' % rec["id"][:8] + ' ' + '%s' % num + ' ' + name + "" + mail + sign + "\n" + ' ' + stamp + "\n" + '%s\n' % (rec["id"][:8], rec["id"][:8]) + attach + "
\n" + '
\n' % rec["id"][:8] + " " + body + "
\n" + remove + "
\n" + "
\n\n") def print_form(self, cache): self.stdout.write( "
\n" + "

\n" + ' \n' + '

\n
\n') if re.search(config.admin, self.environ["REMOTE_ADDR"]): readonly = "" else: readonly = 'readonly="readonly"' if cache.size <= config.file_limit*1024*1024: self.print_post_form(cache, readonly=readonly) def print_post_form(self, cache, readonly=""): self.stdout.write( '

\n' + ' \n' + ' \n' + ' \n' + ' ' + ' ' + self.message["send"] + "\n" + ' ' + ' ' + self.message["error"] + "\n
\n" + ' ' + self.message["name"] + ':\n' + ' ' + self.message["mail"] + ':\n' + ' ' + self.message["signature"] + ':
\n' + " " + self.message["attach"] + ':\n' + ' ' + self.message["suffix"] + ':" + "(" + self.message["limit"] + ": " + str(config.file_limit) + self.message["mb"] + ")
\n" + ' \n' + '

\n') def print_attach(self, datfile, id, stamp, suffix): """Print attachment.""" cache = Cache(datfile) (type, null) = mimetypes.guess_type("." + suffix) if type is None: type = "text/plain" if cache.exists(): pass elif self.check_get_cache(): self.get_cache(cache) else: self.print404(cache) return try: rec = cache[stamp + "_" + id] except KeyError: self.print404(cache) return attach_file = rec.attach_path() if attach_file is not None: self.stdout.write( "Content-Type: " + type + "\n" + "Last-Modified: " + self.rfc822_time(stamp) + "\n" + "Content-Length: " + str(rec.attach_size()) + "\n" + "\n") try: f = file(attach_file, "rb") buf = f.read(1024) while (buf != ""): self.stdout.write(buf) buf = f.read(1024) f.close() except IOError: self.print404(cache)