Changeset 65

Show
Ignore:
Timestamp:
07/27/07 01:17:10 (1 year ago)
Author:
edsuom
Message:

Project download page resource

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • projects/Twisted-Goodies/trunk/misc/var_www_foss.tellectual.com_index.py

    r62 r65  
    9191    def __init__(self, vhostPath): 
    9292        self.vhostPath = vhostPath 
    93         self.apiDocResource = APIDocResource( 
    94             vhostPath, self.projectURLProto, self.projectRepoProto) 
    95         self.downloadResource = DownloadResource( 
    96             vhostPath, self.projectRepoProto) 
     93        args = (vhostPath, self.projectURLProto, self.projectRepoProto) 
     94        self.apiDocResource = APIDocResource(*args) 
     95        self.downloadResource = DownloadResource(*args) 
    9796 
    9897        self.title = "Ed Suominen's Free & Open Source Software Projects" 
  • projects/Twisted-Goodies/trunk/twisted_goodies/simpleserver/http/resources/basic.py

    r61 r65  
    2323""" 
    2424 
     25from twisted.internet import defer 
    2526from twisted.web2 import http, http_headers 
    2627from twisted.web2.resource import Resource 
  • projects/Twisted-Goodies/trunk/twisted_goodies/simpleserver/http/resources/projects.py

    r64 r65  
    2626from twisted.internet import defer, utils 
    2727from twisted.python import procutils 
     28from twisted.web2 import static 
    2829from twisted.web2.resource import Resource, RedirectResource 
    2930 
    30 from basic import StanResource 
    31  
    32  
    33 class APIDocResource(Resource): 
    34     """ 
    35     I provide Web access to generated API documentation for projects hosted 
    36     within a particular I{vhostPath}. 
    37     """ 
    38     re_rev = re.compile(r"Revision:\s+(\d+)") 
    39      
     31from basic import T, StanResource 
     32 
     33 
     34class Mixin(object): 
    4035    def __init__(self, vhostPath, projectURLProto, projectRepoProto): 
    4136        self.vhostPath = os.path.realpath(vhostPath) 
     
    4540                raise ValueError("Invalid string prototype '%s'" % string) 
    4641            setattr(self, name, string) 
     42     
     43 
     44class APIDocResource(Mixin, Resource): 
     45    """ 
     46    I provide Web access to generated API documentation for projects hosted 
     47    within a particular I{vhostPath}. 
     48    """ 
     49    re_rev = re.compile(r"Revision:\s+(\d+)") 
    4750 
    4851    def _executable(self, name): 
     
    8790        that fires when done.  Otherwise, returns nothing. 
    8891        """ 
     92        def lastRev(rev=None): 
     93            if rev is None: 
     94                if not os.path.exists(revFile): 
     95                    return 
     96                fh = open(revFile) 
     97                rev = fh.readline().strip() 
     98            else: 
     99                revDir = os.path.dirname(revFile) 
     100                if not os.path.exists(revDir): 
     101                    os.makedirs(revDir) 
     102                fh = open(revFile, 'w') 
     103                fh.write(str(rev)) 
     104            fh.close() 
     105            return rev 
     106         
    89107        def compareRevs(currentRev): 
    90             if currentRev != docRev
     108            if currentRev != lastRev()
    91109                # Tell the world that the docs are at the new rev... 
    92                 fh = open(revFile, 'w') 
    93                 fh.write(currentRev) 
    94                 fh.close() 
     110                lastRev(currentRev) 
    95111                # ...then make good on that (just once) 
    96112                tmpDir = tempfile.mkdtemp() 
     
    98114                d.addCallback(lambda _: self.pydoctor(tmpDir, projectName)) 
    99115                d.addCallback(lambda _: shutil.rmtree(tmpDir)) 
    100                 d.addCallback(lambda _: writeNewRev(currentRev)) 
    101116                return d 
    102          
     117 
    103118        revFile = os.path.join(self.vhostPath, 'api', projectName, 'REV') 
    104         if os.path.exists(revFile): 
    105             # The rev for which the current docs were generated 
    106             fh = open(revFile) 
    107             docRev = fh.readline().strip() 
    108             fh.close() 
    109             # Get and compare to the current rev 
    110             d = self.svnRev(projectName) 
    111             d.addCallback(compareRevs) 
    112             return d 
     119        return self.svnRev(projectName).addCallback(compareRevs) 
    113120 
    114121    def svnRev(self, projectName): 
     
    163170 
    164171 
    165 class DownloadResource(StanResource): 
     172class DownloadResource(Mixin, StanResource): 
    166173    """ 
    167174    I provide a page of HTML that shows the different ways to download projects 
    168175    hosted within a particular I{vhostPath}. 
    169176    """ 
    170     addSlash = True 
    171      
    172     def __init__(self, vhostPath, projectRepoProto): 
    173         self.vhostPath = vhostPath 
    174         if "%s" not in projectRepoProto: 
    175             raise ValueError("Invalid project repo prototype") 
    176         self.projectRepoProto = projectRepoProto 
     177    downloadURLProto = "/download/%s" 
     178    style = { 
     179        "H1":\ 
     180        {'margin-bottom':'0px'}, 
     181 
     182        "H2":\ 
     183        {'margin-bottom':'0px'}, 
     184         
     185        "code":\ 
     186        {'padding':'0.3em', 
     187         'margin-left':'0.5em', 
     188         'font-size':'larger', 
     189         'font-style':'bold', 
     190         'font-family':'monospace'} 
     191        } 
     192 
     193    def _pertinentFiles(self): 
     194        downloadDir = os.path.join(self.vhostPath, 'download') 
     195        listing = [] 
     196        for fileName in os.listdir(downloadDir): 
     197            if not fileName.startswith(self.projectName): 
     198                continue 
     199            listing.append(fileName) 
     200        return downloadDir, listing 
     201 
     202    def _sectionEasyInstall(self): 
     203        return [ 
     204            T.h2["Setup Tools (the easiest way)"], 
     205            T.p(id="code")["easy_install %s" % self.projectName]] 
     206 
     207    def _sectionInstallFiles(self): 
     208        listing = [] 
     209        for fileName in self._pertinentFiles()[1]: 
     210            href = self.downloadURLProto % fileName 
     211            item = T.li[T.a(href=href)[fileName]] 
     212            listing.append(item) 
     213        return [T.h2["Install Files"], T.ul[listing]] 
    177214 
    178215    def render(self, request): 
     
    180217        Returns the body of my HTML. 
    181218        """ 
    182         body = [ 
    183             T.h2["Setup Tools (the easiest way)"], 
    184             T.p["easy_install %s" % self.projectName]] 
     219        msg = "There are a couple of different ways to get up and running "+\ 
     220              "with a copy of %s:" % self.projectName 
     221        body  = [T.img(src='/banner.png'), T.hr, T.h1[self.title], T.p[msg]] 
     222        body += self._sectionEasyInstall() 
     223        body += self._sectionInstallFiles() 
     224        href = self.projectURLProto % self.projectName 
     225        body += [T.hr, T.a(href=href)["Back to Project Page"]] 
    185226        return body 
    186227 
    187228    def locateChild(self, request, segments): 
    188229        self.projectName = segments[0] 
    189         self.title = "How to Download %s" % self.projectName 
    190         if len(segments) == 1: 
    191             return self, () 
     230        self.title = "Downloading %s" % self.projectName 
     231        if len(segments) > 1: 
     232            downloadDir, downloadFiles = self._pertinentFiles() 
     233            if segments[1] in downloadFiles: 
     234                filePath = os.path.join(downloadDir, segments[1]) 
     235                return static.File(filePath), () 
     236        return self, ()