Changeset 71
- Timestamp:
- 08/06/07 13:49:41 (1 year ago)
- Files:
-
- projects/Consolation/trunk/MANIFEST.in (added)
- projects/Consolation/trunk/scripts (added)
- projects/Consolation/trunk/scripts/quelle (moved) (moved from projects/Consolation/trunk/quelle) (7 diffs)
- projects/Consolation/trunk/setup.py (added)
- projects/sAsync/trunk/doc (deleted)
- projects/Twisted-Goodies/trunk/doc (deleted)
- projects/Twisted-Goodies/trunk/misc/var_www_foss.tellectual.com_index.py (modified) (2 diffs)
- projects/Twisted-Goodies/trunk/twisted_goodies/simpleserver/http/resources/projects.py (modified) (4 diffs)
- projects/Twisted-Goodies/trunk/twisted_goodies/simpleserver/http/wsgi.py (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
projects/Consolation/trunk/scripts/quelle
r46 r71 57 57 58 58 def 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 """ 59 66 if len(args) == 2: 60 67 msgProto = " %2s %s" … … 167 174 168 175 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 """ 169 181 sequence.sort() 170 182 bothRoots = self.archiveMgr.pathPair(root) … … 172 184 yield [os.path.join(x, element) for x in bothRoots] 173 185 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 """ 175 194 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): 179 198 ID = len(self.filesLogged)-1 180 log(ID, possibleString[:2], sysPath)199 log(ID, possibleString[:2], paths[-1]) 181 200 else: 182 log(possibleString[:2], sysPath)201 log(possibleString[:2], paths[-1]) 183 202 184 203 def run(self, directory, **kw): … … 195 214 two characters are symbols that refer to the archive and system-root 196 215 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. 197 221 """ 198 222 self.filesLogged = [] 199 223 mkdirs = kw.get('mkdirs', False) 200 224 topdown = kw.get('topdown', True) 225 arcOnly = kw.get('arcOnly', False) 226 funcFile = kw.get('funcFile', None) 201 227 self.showIDs = kw.get('showIDs', False) 202 228 for root, dirs, files in os.walk(directory, topdown=topdown): … … 206 232 if not os.path.exists(thisDir): 207 233 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) 209 242 for arcFile, sysFile in self.generatePairs(root, files): 210 243 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) 214 250 215 251 … … 299 335 self.archiveDir, funcFile=syncFiles, mkdirs=True) 300 336 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): 302 356 """ 303 357 Removes the specified file or directory I{path} in my system root, 304 358 including any files and subdirectories. Any corresponding version in my 305 359 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) 315 368 316 369 if os.path.isdir(path): 317 370 self.patherator.run( 318 371 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) 326 382 327 383 def copyPath(self, somePath): … … 413 469 """ 414 470 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) 415 479 416 480 def revert(self, *paths): projects/Twisted-Goodies/trunk/misc/var_www_foss.tellectual.com_index.py
r69 r71 79 79 80 80 81 class 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 81 94 class Resource(StanResource): 82 95 """ … … 209 222 listOp('append', 'wiki') 210 223 root, isAtRoot = rootState(subSegments) 224 if root == 'changeset': 225 # TODO, hopefully won't need this long 226 return DisabledResource("Changeset Listings"), () 211 227 if root == 'wiki' and len(subSegments) > 1: 212 228 subRoot = subSegments[1] projects/Twisted-Goodies/trunk/twisted_goodies/simpleserver/http/resources/projects.py
r69 r71 73 73 newURL = (request.scheme, request.host, urlPath, '', '', '') 74 74 return RedirectResource(*newURL), () 75 75 76 print "APIDocResource", segments 76 77 projectName = segments[0] 77 78 if len(segments) > 1: … … 213 214 T.h2["SVN Checkout"], 214 215 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"], 217 219 T.p(id="code")["sudo python setup.py install"]] 218 220 … … 224 226 item = T.li[T.a(href=href)[fileName]] 225 227 listing.append(item) 228 if not listing: 229 return [] 226 230 return [ 227 231 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 "+\ 230 235 "\".exe\" files) or extracting their archived files and "+\ 231 236 "using the setup.py script."], … … 247 252 248 253 def locateChild(self, request, segments): 254 print "DownloadResource", segments 249 255 self.projectName = segments[0] 250 256 self.title = "Downloading %s" % self.projectName projects/Twisted-Goodies/trunk/twisted_goodies/simpleserver/http/wsgi.py
r59 r71 24 24 """ 25 25 26 import os, threading 26 import os, threading, sys 27 27 import Queue 28 28 from zope.interface import implements … … 63 63 64 64 65 class WSGIResource(object): 65 class 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 138 class WSGIResource(TracerMixin, object): 66 139 """ 67 140 A web2 Resource which wraps the given WSGI application callable. … … 98 171 handler = WSGIHandler(self.application, req) 99 172 self.handlers.append(handler) 100 if VERBOSE:101 print "Next handler:", handler102 173 # 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)) 104 179 d.addBoth(done, IP) 105 180 # We get the result piecemeal from this method call's unique handler, … … 121 196 delayedCall = reactor.callLater(IP_BAN_SECS, d.callback, IP) 122 197 self.banned[IP] = d, delayedCall 123 198 124 199 def denial(self): 125 200 title = "Access Denied" … … 363 438 """ 364 439 """ 365 if VERBOSE:366 print "Running next WSGI application..."367 440 self.ok = True 368 441 from twisted.internet import reactor … … 380 453 def __callback(self): 381 454 # Called in IO thread 382 if VERBOSE:383 print "Done (ok):", self384 455 self.responseDeferred.callback(self.response) 385 456 self.responseDeferred = None … … 387 458 def __error(self, f): 388 459 # Called in IO thread 389 if VERBOSE:390 print "Done (error):", self391 460 self.responseDeferred.errback(f) 392 461 self.responseDeferred = None
