Below is the file 'links.py' from this revision. You can also download the file.
# Copyright (C) 2005 Grahame Bowland <grahame@angrygoats.net> # # This program is made available under the GNU GPL version 2.0 or # greater. See the accompanying file COPYING for details. # # This program is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # PURPOSE. # # links.py: # link to various objects within a monotone database # import urllib, urlparse, cgi, binascii, rfc822 import json import config hq = cgi.escape class Link(object): def __init__(self, description=None, link_type=None, **kwargs): self.absolute_uri = None self.relative_uri = None self.description = description self.json_args = None self.ctxt = kwargs['ctxt'] def nbhq(self, s): return ' '.join([hq(t) for t in s.split(' ')]) def uri(self): if not self.absolute_uri is None: return self.absolute_uri elif not self.relative_uri is None: return self.ctxt.perdb_join(self.relative_uri) else: return None def html(self, override_description=None, force_nbsp=False): if override_description: if force_nbsp: d = self.nbhq(override_description) else: d = hq(override_description) else: d = self.description uri = self.uri() if uri is None: return hq(self.description) rv = '<a href="%s">%s</a>' % (uri, d) if self.json_args != None: enc_args = binascii.hexlify(json.write(self.json_args)) rv = '<span id="js_%s" class="%s">' % (hq(enc_args), hq(str(self.__class__).split('.')[-1])) + rv + '</span>' return rv class AuthorLink(Link): def __init__(self, author, **kwargs): Link.__init__(*(self, ), **kwargs) name, email = rfc822.parseaddr(author) self.description = author if email: self.absolute_uri = "mailto:%s" % urllib.quote(email) if name: self.description = hq(name) class RevisionLink(Link): def __init__(self, revision, **kwargs): link_type = kwargs.get("link_type") if link_type == "browse": subpage = "browse" else: subpage = "info" Link.__init__(*(self, ), **kwargs) self.json_args = [str(revision)] self.relative_uri = 'revision/%s/%s' % (subpage, revision) self.description = revision.abbrev() class TagLink(Link): def __init__(self, tag, **kwargs): Link.__init__(*(self, ), **kwargs) self.relative_uri = 'revision/info/%s' % (tag.revision) self.description = tag.name class BranchLink(Link): def __init__(self, branch, **kwargs): Link.__init__(*(self, ), **kwargs) self.json_args = [branch.name] from_change, to_change = kwargs.get('from_change'), kwargs.get('to_change') if from_change and to_change: self.relative_uri = 'branch/changes/%s/from/%d/to/%d' % (urllib.quote(branch.name, safe = ''), from_change, to_change) else: self.relative_uri = 'branch/changes/' + urllib.quote(branch.name, safe = '') self.description = hq(branch.name) class DiffLink(Link): def __init__(self, diff, **kwargs): Link.__init__(*(self, ), **kwargs) if kwargs.get('link_type', None) == "raw": mode = "rawdiff" else: mode = "diff" self.relative_uri = 'revision/%s/' % (mode) + diff.from_rev + '/with/' + diff.to_rev if isinstance(diff.fname, list): # TODO: figure out a linking scheme for diffs of multiple files. if len(diff.fname) > 0: fname = diff.fname[0] else: fname = None else: fname = diff.fname if fname is not None: self.relative_uri += '/'+urllib.quote(fname) self.description = "diff" class DirLink(Link): def __init__(self, file, **kwargs): Link.__init__(*(self, ), **kwargs) # handle the root directory if file.name == '/': fn = '' else: fn = file.name self.relative_uri = 'revision/browse/' + file.in_revision + '/' + urllib.quote(fn) self.description = hq(file.name) class FileLink(Link): def __init__(self, file, **kwargs): Link.__init__(*(self, ), **kwargs) if kwargs.has_key('for_download'): access_method = 'downloadfile' elif kwargs.has_key('for_changes'): access_method = 'filechanges' elif kwargs.has_key('for_changes_rss'): access_method = 'filechanges/rss' else: access_method = 'file' self.relative_uri = 'revision/' + access_method + '/' + file.in_revision + '/' + urllib.quote(file.name) self.description = hq(file.name) type_to_link_class = { 'author' : AuthorLink, 'branch' : BranchLink, 'diff' : DiffLink, 'dir' : DirLink, 'file' : FileLink, 'revision' : RevisionLink, 'tag' : TagLink, } def link(obj, link_type=None, **kwargs): link_class = type_to_link_class.get(obj.obj_type) if not link_class: raise LinkException("Unable to link to objects of type: '%s'" % (obj.obj_type)) # bodgy, but can't give named arguments from the templates so we need to # have the second argument go into link_type if not link_type is None: kwargs['link_type'] = link_type rv = link_class(obj, **kwargs) return rv