diff options
Diffstat (limited to 'patchtracker/ReqHandler.py')
-rwxr-xr-x | patchtracker/ReqHandler.py | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/patchtracker/ReqHandler.py b/patchtracker/ReqHandler.py new file mode 100755 index 0000000..7f0dbc0 --- /dev/null +++ b/patchtracker/ReqHandler.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- + +from mod_python import apache, util + +import cgi +import os +import sys + +import patchtracker.Conf as Conf +from patchtracker.Templates import ErrorTemplate, PatchTemplate, PackageVersTemplate, LetterTocTemplate, FrontPageTemplate, SearchResultsTemplate +from patchtracker.DiffGzHandler import DiffGzHandler +import patchtracker.DB as DB +from patchtracker.DB import PatchTrackerDB +import pygments +from pygments.lexers import DiffLexer +from pygments.formatters import HtmlFormatter +import patchtracker.SourceArchive as SourceArchive + +def error(msg, code=apache.HTTP_INTERNAL_SERVER_ERROR): + Client.req.status = code + Client.req.write(str(ErrorTemplate(msg))) + raise apache.SERVER_RETURN, apache.OK + +class Error404Cmd: + def __init__(self, msg): + Client.req.status = apache.HTTP_NOT_FOUND + self.msg = msg + + def output(self): + return str(ErrorTemplate(self.msg)) + +class Client: + req = None + +class PatchCmd: + def __init__(self, args): + self.db = PatchTrackerDB() + self.patchtype,mode,pkgname,version = args[0:4] + self.parsemode(mode) + dh = self.make_diffhandler(pkgname,version) + if self.patchtype == "series": + self.patchname = os.sep.join(args[4:]) + self.content = dh.series().fetch(self.patchname) + elif self.patchtype == "debianonly": + self.patchname = "debian-dir only changes" + self.content = dh.debiandir() + elif self.patchtype == "nondebian": + self.patchname = "direct (non packaging) changes" + self.content = dh.nondebiandir() + elif self.patchtype == "misc": + self.patchname = os.sep.join(args[4:]) + self.content = dh.filterdiff(include=self.patchname) + else: + error("unhandled patch type '%s'"%(self.patchtype)) + self.pkgname = pkgname + self.version = version + + def parsemode(self, mode): + if mode == "view" or mode == "dl": + self.mode = mode + else: + error("unhandled display mode '%s'"%(mode)) + + def make_diffhandler(self, pkgname, vers): + dfile = self.db.findDiffGz(pkgname,vers) + if dfile: + return DiffGzHandler(dfile) + else: + error("can not find diff file for %s / %s"%(pkgname,vers)) + + def output(self): + if self.mode == "dl": + Client.req.content_type = "text/x-diff" + return str(self.content) + else: + return str(PatchTemplate(pkg=self.pkgname,vers=self.version, + patch=self.content,name=self.patchname, + patchtype=self.patchtype)) + +class PackageCmd: + def __init__(self, args): + db = PatchTrackerDB() + self.name = args[0] + if len(args) > 1: + version = args[1] + else: + version = None + self.toc = db.findCollection(package=self.name, version=version) + if self.toc.size() == 0: + if len(self.name) >= 3: + self.toc = db.findCollection(package="%"+self.name+"%", version=version) + + def output(self): + plist = self.toc.getletter(self.name) + if len(self.name) < 3: + error("search terms must be 3 or more letters...") + if not plist or len(plist) == 0: + error("can't find any package named or containing '%s'"%self.name) + else: + p = self.toc.getpackage(self.name) + # if there is no match, or if multiple versions were returned + if not p or len(set(map(lambda x: x.version, p.values()))) > 1: + querydesc = "package name contains" + return str(SearchResultsTemplate(self.name, querydesc, self.toc)) + else: + return str(PackageVersTemplate(p.popitem()[1])) + +class IndexCmd: + def __init__(self, args): + if len(args) < 1 or not len(args[0]): + error("please provide a letter on which to index") + else: + self.db = PatchTrackerDB() + self.letter = args[0] + self.toc = self.db.findLetterToc(self.letter) + + def output(self): + return str(LetterTocTemplate(self.letter, self.toc)) + +class MaintCmd: + def __init__(self, args): + if len(args) < 1 or not len(args[0]): + error("please provide a email address on which to index") + else: + self.db = PatchTrackerDB() + self.email = args[0] + self.toc = self.db.findCollection(email=self.email) + + def output(self): + return str(SearchResultsTemplate(self.email, "maintainer email", self.toc)) + +class JumpCmd: + def __init__(self): + form = util.FieldStorage(Client.req) + self.name = form.getfirst("package") + + def output(self): + uri = "http://%s%s/package/%s"%(Client.req.hostname, Conf.root_url, self.name) + Client.req.headers_out["Location"] = uri + raise apache.SERVER_RETURN, apache.HTTP_MOVED_TEMPORARILY + +class FrontPageCmd: + def __init__(self): + self.db = PatchTrackerDB() + self.index = self.db.findIndices() + + def output(self): + return str(FrontPageTemplate(self.index)) + +class CmdHandler: + def __init__(self, req): + req.content_type = "text/html" + uri=req.uri + if len(uri)<len(Conf.root_url) or uri[0:len(Conf.root_url)]!=Conf.root_url: + error("Invalid URL!") + + args = uri[len(Conf.root_url)+1:].split("/") + cmdarg = args[0] + if cmdarg == "patch": + self.cmd = PatchCmd(args[1:]) + elif cmdarg == "package": + self.cmd = PackageCmd(args[1:]) + elif cmdarg == "index": + self.cmd = IndexCmd(args[1:]) + elif cmdarg == "jump": + self.cmd = JumpCmd() + elif cmdarg == "email": + self.cmd = MaintCmd(args[1:]) + elif not len(cmdarg): + self.cmd = FrontPageCmd() + else: + self.cmd = Error404Cmd("invalid command/location '%s'"%(cmdarg)) + + def output(self): + return self.cmd.output() |