Changeset 71

Show
Ignore:
Timestamp:
08/06/07 13:49:41 (1 year ago)
Author:
edsuom
Message:

Setup installation for Consolation scripts; wsgi debugging

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • projects/Consolation/trunk/scripts/quelle

    r46 r71  
    5757 
    5858def log(*args): 
     59    """ 
     60    Logs a message preceded by a two-character status code and, optionally, by 
     61    an integer file reference. 
     62 
     63    The status code's characters indicate the archive and system-root versions 
     64    of the file, respectively. 
     65    """ 
    5966    if len(args) == 2: 
    6067        msgProto = "  %2s %s" 
     
    167174     
    168175    def generatePairs(self, root, sequence): 
     176        """ 
     177        Yields lists containing the archive and system-root versions, 
     178        respectively, of each file in the supplied I{sequence} that is present 
     179        in the specified I{root}. 
     180        """ 
    169181        sequence.sort() 
    170182        bothRoots = self.archiveMgr.pathPair(root) 
     
    172184            yield [os.path.join(x, element) for x in bothRoots] 
    173185 
    174     def processPair(self, f, arcPath, sysPath, showID=False): 
     186    def processPaths(self, f, *paths, **kw): 
     187        """ 
     188        Using the supplied callable I{f}, processes the path(s) supplied as 
     189        additional arguments. 
     190 
     191        If the callable returns a string, logs the operation, with the path ID 
     192        if I{showID} is set C{True}. 
     193        """ 
    175194        if callable(f): 
    176             possibleString = f(arcPath, sysPath
    177             if possibleString
    178                 if showID
     195            possibleString = f(*paths
     196            if possibleString and isinstance(possibleString, str)
     197                if kw.get('showID', False)
    179198                    ID = len(self.filesLogged)-1  
    180                     log(ID, possibleString[:2], sysPath
     199                    log(ID, possibleString[:2], paths[-1]
    181200                else: 
    182                     log(possibleString[:2], sysPath
     201                    log(possibleString[:2], paths[-1]
    183202     
    184203    def run(self, directory, **kw): 
     
    195214        two characters are symbols that refer to the archive and system-root 
    196215        versions of the path operated on by the function. 
     216 
     217        If I{arcOnly} is set C{True}, each operation is performed only for the 
     218        archive version of each path encountered. In that case, each supplied 
     219        callable object must be prepared to accept just a single argument 
     220        rather than two. 
    197221        """ 
    198222        self.filesLogged = [] 
    199223        mkdirs = kw.get('mkdirs', False) 
    200224        topdown = kw.get('topdown', True) 
     225        arcOnly = kw.get('arcOnly', False) 
     226        funcFile = kw.get('funcFile', None) 
    201227        self.showIDs = kw.get('showIDs', False) 
    202228        for root, dirs, files in os.walk(directory, topdown=topdown): 
     
    206232                        if not os.path.exists(thisDir): 
    207233                            os.mkdir(thisDir) 
    208                 self.processPair(kw.get('funcDir', None), *dirPair) 
     234                        if arcOnly: 
     235                            break 
     236                args = [kw.get('funcDir', None)] 
     237                if arcOnly: 
     238                    args.append(dirPair[0]) 
     239                else: 
     240                    args.extend(dirPair) 
     241                self.processPaths(*args) 
    209242            for arcFile, sysFile in self.generatePairs(root, files): 
    210243                self.filesLogged.append(sysFile) 
    211                 self.processPair( 
    212                     kw.get('funcFile', None), 
    213                     arcFile, sysFile, showID=self.showIDs) 
     244                if arcOnly: 
     245                    self.processPaths( 
     246                        funcFile, arcFile, showID=self.showIDs) 
     247                else: 
     248                    self.processPaths( 
     249                        funcFile, arcFile, sysFile, showID=self.showIDs) 
    214250 
    215251 
     
    299335            self.archiveDir, funcFile=syncFiles, mkdirs=True) 
    300336 
    301     def rmTree(self, path): 
     337    def remove(self, remover, test, *paths): 
     338        """ 
     339        Removes each of the specified I{paths} supplied as argument beyond the 
     340        first two. Uses the supplied I{remover} callable with one paths as its 
     341        argument , and does the removal for each path only if the supplied 
     342        I{test} callable returns C{True} for that path. 
     343 
     344        Returns a list of the standard two-character status codes, one for each 
     345        path. 
     346        """ 
     347        deleted = [False, False] 
     348        for k, thisPath in enumerate(paths): 
     349            isPresent = test(thisPath) 
     350            deleted[k] = isPresent 
     351            if isPresent and not self.dryRun: 
     352                remover(thisPath) 
     353        return "".join([("-", "D")[x] for x in deleted]) 
     354 
     355    def rmTree(self, path, arcOnly=False): 
    302356        """ 
    303357        Removes the specified file or directory I{path} in my system root, 
    304358        including any files and subdirectories. Any corresponding version in my 
    305359        archive directory is removed as well. 
    306         """ 
    307         def remove(remover, test, *paths): 
    308             deleted = [] 
    309             for thisPath in paths: 
    310                 isPresent = test(thisPath) 
    311                 deleted.append(isPresent) 
    312                 if isPresent and not self.dryRun: 
    313                     remover(thisPath) 
    314             return "".join([("-", "D")[x] for x in deleted]) 
     360 
     361        If I{arcOnly} is set C{True}, only the archive version is removed. 
     362        """ 
     363        def dirRemover(*paths): 
     364            return self.remove(os.rmdir, os.path.isdir, *paths) 
     365 
     366        def fileRemover(*paths): 
     367            return self.remove(os.remove, os.path.isfile, *paths) 
    315368 
    316369        if os.path.isdir(path): 
    317370            self.patherator.run( 
    318371                path, 
    319                 funcDir=lambda x,y: remove(os.rmdir, os.path.isdir, x, y), 
    320                 funcFile=lambda x,y: remove(os.remove, os.path.isfile, x, y), 
    321                 topdown=False) 
    322         else: 
    323             arcFile, sysFile = self.archiveMgr.pathPair(path) 
    324             statusCode = remove(os.remove, os.path.isfile, arcFile, sysFile) 
    325             log(statusCode, sysFile) 
     372                funcDir=dirRemover, 
     373                funcFile=fileRemover, 
     374                topdown=False, arcOnly=arcOnly) 
     375            return 
     376        arcFile, sysFile = self.archiveMgr.pathPair(path) 
     377        if arcOnly: 
     378            statusCode = fileRemover(arcFile) 
     379        else: 
     380            statusCode = fileRemover(arcFile, sysFile) 
     381        log(statusCode, sysFile) 
    326382     
    327383    def copyPath(self, somePath): 
     
    413469        """ 
    414470        self.sync.syncTree() 
     471 
     472    def unlink(self, *paths): 
     473        """ 
     474        Unlinks the file or directory path(s) in the root filesystem from the 
     475        archive, removing the archived version(s). 
     476        """ 
     477        for path in paths: 
     478            self.sync.rmTree(path, arcOnly=True) 
    415479 
    416480    def revert(self, *paths): 
  • projects/Twisted-Goodies/trunk/misc/var_www_foss.tellectual.com_index.py

    r69 r71  
    7979 
    8080 
     81class DisabledResource(StanResource): 
     82    addSlash = False 
     83 
     84    def __init__(self, whatDisabled): 
     85        self.whatDisabled = whatDisabled 
     86        self.title = "%s Temporarily Disabled" % whatDisabled 
     87 
     88    def render(self, request): 
     89        return [ 
     90            T.h2[self.title], 
     91            T.p["Hopefully this should be fixed soon."]] 
     92 
     93 
    8194class Resource(StanResource): 
    8295    """ 
     
    209222            listOp('append', 'wiki') 
    210223        root, isAtRoot = rootState(subSegments) 
     224        if root == 'changeset': 
     225            # TODO, hopefully won't need this long 
     226            return DisabledResource("Changeset Listings"), () 
    211227        if root == 'wiki' and len(subSegments) > 1: 
    212228            subRoot = subSegments[1] 
  • projects/Twisted-Goodies/trunk/twisted_goodies/simpleserver/http/resources/projects.py

    r69 r71  
    7373            newURL = (request.scheme, request.host, urlPath, '', '', '') 
    7474            return RedirectResource(*newURL), () 
    75          
     75 
     76        print "APIDocResource", segments 
    7677        projectName = segments[0] 
    7778        if len(segments) > 1: 
     
    213214            T.h2["SVN Checkout"], 
    214215            T.p(id="code")["svn co %s %s" % (url, self.projectName)], 
    215             T.p["The current source code (\"trunk\") will appear in the "+\ 
    216                 "\"%s\" subdirectory. You can go there and install with"], 
     216            T.p["The current source code (\"trunk\") will appear in the " +\ 
     217                "\"%s\" subdirectory. " % self.projectName +\ 
     218                "You can go there and install with"], 
    217219            T.p(id="code")["sudo python setup.py install"]] 
    218220         
     
    224226                item = T.li[T.a(href=href)[fileName]] 
    225227                listing.append(item) 
     228        if not listing: 
     229            return [] 
    226230        return [ 
    227231            T.h2["Install Files"], 
    228             T.p["You can download one of the following files and use it to "+\ 
    229                 "install %s, either by executing them (for Windows "+\ 
     232            T.p["You can download one of the following files and use it to " +\ 
     233                "install %s, either by " % self.projectName +\ 
     234                "executing them (for Windows "+\ 
    230235                "\".exe\" files) or extracting their archived files and "+\ 
    231236                "using the setup.py script."], 
     
    247252 
    248253    def locateChild(self, request, segments): 
     254        print "DownloadResource", segments 
    249255        self.projectName = segments[0] 
    250256        self.title = "Downloading %s" % self.projectName 
  • projects/Twisted-Goodies/trunk/twisted_goodies/simpleserver/http/wsgi.py

    r59 r71  
    2424""" 
    2525 
    26 import os, threading 
     26import os, threading, sys 
    2727import Queue 
    2828from zope.interface import implements 
     
    6363 
    6464 
    65 class WSGIResource(object): 
     65class TracerMixin(object): 
     66    """ 
     67    Mix me in to trace problems 
     68    """ 
     69    isTracing = False 
     70    traceFrame = None 
     71    traceStack = [ 
     72        # Bottom frame on up, just like a stack... 
     73        ('cache.py', 'get_changes'), 
     74        ('changeset.py', 'get_changes'), 
     75        ('changeset.py', '_render_html') 
     76        ] 
     77    traceLevels = 5 
     78     
     79    def settrace(self): 
     80        """ 
     81        Call this method to start tracing. If you're using threads, you must 
     82        call it within the same thread whose execution you want to trace. 
     83        """ 
     84        sys.settrace(self.trace) 
     85        self.isTracing = True 
     86 
     87    def trace(self, frame, event, arg): 
     88        """ 
     89        This is the actual trace function. 
     90        """ 
     91        def msg(level): 
     92            values = ["." * level] 
     93            values.extend([ 
     94                getattr(frame.f_code, "co_%s" % x) 
     95                for x in ('filename', 'firstlineno', 'name')]) 
     96            if values != getattr(self, '_prevMsgValues', None): 
     97                self._prevMsgValues = values 
     98                print "%s %s (%04d): %s" % tuple(values) 
     99 
     100        def isTraceEntry(k, thisFrame): 
     101            if thisFrame.f_code.co_name == self.traceStack[k][1]: 
     102                tail = "/%s" % self.traceStack[k][0] 
     103                if thisFrame.f_code.co_filename.endswith(tail): 
     104                    return True 
     105 
     106        def frameGenerator(N): 
     107            nextFrame = frame 
     108            for k in xrange(N): 
     109                yield k, nextFrame 
     110                nextFrame = nextFrame.f_back 
     111 
     112        if not self.isTracing: 
     113            return 
     114        if event == 'call': 
     115            level = 1 
     116            if self.traceFrame is None: 
     117                N = len(self.traceStack) 
     118                for k, thisFrame in frameGenerator(N): 
     119                    if not isTraceEntry(k, thisFrame): 
     120                        return 
     121                else: 
     122                    print "-" * 40 
     123                    self.traceFrame = frame 
     124            else: 
     125                for k, thisFrame in frameGenerator(self.traceLevels): 
     126                    level += 1 
     127                    if thisFrame in (None, self.traceFrame): 
     128                        break 
     129                else: 
     130                    return 
     131            msg(level) 
     132            return self.trace 
     133        elif event == 'return' and frame == self.traceFrame: 
     134            self.traceFrame = None 
     135            print "->", arg 
     136 
     137 
     138class WSGIResource(TracerMixin, object): 
    66139    """ 
    67140    A web2 Resource which wraps the given WSGI application callable. 
     
    98171        handler = WSGIHandler(self.application, req) 
    99172        self.handlers.append(handler) 
    100         if VERBOSE: 
    101             print "Next handler:", handler 
    102173        # Queue it up for running in the thread 
    103         d = self.queue.call(handler.run) 
     174        if self.isTracing: 
     175            d = defer.succeed(None) 
     176        else: 
     177            d = self.queue.call(self.settrace) 
     178        d.addCallback(lambda _: self.queue.call(handler.run)) 
    104179        d.addBoth(done, IP) 
    105180        # We get the result piecemeal from this method call's unique handler, 
     
    121196        delayedCall = reactor.callLater(IP_BAN_SECS, d.callback, IP) 
    122197        self.banned[IP] = d, delayedCall 
    123  
     198     
    124199    def denial(self): 
    125200        title = "Access Denied" 
     
    363438        """ 
    364439        """ 
    365         if VERBOSE: 
    366             print "Running next WSGI application..." 
    367440        self.ok = True 
    368441        from twisted.internet import reactor 
     
    380453    def __callback(self): 
    381454        # Called in IO thread 
    382         if VERBOSE: 
    383             print "Done (ok):", self 
    384455        self.responseDeferred.callback(self.response) 
    385456        self.responseDeferred = None 
     
    387458    def __error(self, f): 
    388459        # Called in IO thread 
    389         if VERBOSE: 
    390             print "Done (error):", self 
    391460        self.responseDeferred.errback(f) 
    392461        self.responseDeferred = None