comparison tincan.py @ 3:c6902cded64d draft

Corrections and reorg.
author David Barts <n5jrn@me.com>
date Mon, 13 May 2019 06:53:08 -0700
parents ca6f8ca38cf2
children 0d47859f792a
comparison
equal deleted inserted replaced
2:ca6f8ca38cf2 3:c6902cded64d
319 hidden = None 319 hidden = None
320 while True: 320 while True:
321 self._template = TemplateFile(self._fspath) 321 self._template = TemplateFile(self._fspath)
322 self._header = TemplateHeader(self._template.header) 322 self._header = TemplateHeader(self._template.header)
323 if hidden is None: 323 if hidden is None:
324 if self._header.errors is not None:
325 break
324 hidden = self._header.hidden 326 hidden = self._header.hidden
327 elif self._header.errors is not None:
328 raise TinCanError("{0}: #forward to #errors not allowed".format(self._origin))
325 if self._header.forward is None: 329 if self._header.forward is None:
326 break 330 break
327 self._redirect() 331 self._redirect()
328 # If this is a hidden page, we ignore it for now, since hidden pages 332 # If this is a hidden page, we ignore it for now, since hidden pages
329 # don't get routes made for them. 333 # don't get routes made for them.
330 if hidden: 334 if hidden:
331 return 335 return
332 # If this is an error page, register it as such. 336 # If this is an error page, register it as such.
333 if self._header.errors is not None: 337 if self._header.errors is not None:
334 if self._header.template is not None: 338 self._mkerror()
335 tpath = os.path.join(self._fsroot, *self._splitpath(self._header.template))
336 self._template =
337 try:
338 errors = [ int(i) for i in self._header.errors.split() ]
339 except ValueError as e:
340 raise TinCanError("{0}: bad #errors line".format(self._urlpath)) from e
341 if not errors:
342 errors = range(_ERRMIN, _ERRMAX+1)
343 route = TinCanErrorRoute(self._tclass(source=self._template.body))
344 for error in errors:
345 if error < _ERRMIN or error > _ERRMAX:
346 raise TinCanError("{0}: bad #errors code".format(self._urlpath))
347 self._app.error(code=error, callback=route)
348 return # this implies #hidden 339 return # this implies #hidden
349 # Get methods for this route 340 # Get methods for this route
350 if self._header.methods is None: 341 if self._header.methods is None:
351 methods = [ 'GET' ] 342 methods = [ 'GET' ]
352 else: 343 else:
353 methods = [ i.upper() for i in self._header.methods.split() ] 344 methods = [ i.upper() for i in self._header.methods.split() ]
345 if not methods:
346 raise TinCanError("{0}: no #methods specified".format(self._urlpath))
354 # Process other header entries 347 # Process other header entries
355 if self._header.python is not None: 348 if self._header.python is not None:
356 if not self._header.python.endswith(_PEXTEN): 349 if not self._header.python.endswith(_PEXTEN):
357 raise TinCanError("{0}: #python files must end in {1}", self._urlpath, _PEXTEN) 350 raise TinCanError("{0}: #python files must end in {1}", self._urlpath, _PEXTEN)
358 self._python = self._header.python 351 self._python = self._header.python
359 # Obtain a class object by importing and introspecting a module. 352 # Obtain a class object by importing and introspecting a module.
353 self._getclass()
354 # Build body object (Chameleon template)
355 if self._header.template is not None:
356 if not self._header.template.endswith(_TEXTEN):
357 raise TinCanError("{0}: #template files must end in {1}", self._urlpath, _TEXTEN)
358 tpath = os.path.join(self._fsroot, *self._splitpath(self._header.template))
359 tfile = TemplateFile(tpath)
360 self._body = self._tclass(source=tfile.body)
361 else:
362 self._body = self._tclass(source=self._template.body)
363 self._body.prepare()
364 # Register this thing with Bottle
365 print("adding route:", self._origin) # debug
366 self._app.route(self._origin, methods, self)
367
368 def _splitpath(self, unsplit):
369 return _normpath(self._subdir, unsplit)
370
371 def _mkerror(self):
372 try:
373 errors = [ int(i) for i in self._header.errors.split() ]
374 except ValueError as e:
375 raise TinCanError("{0}: bad #errors line".format(self._urlpath)) from e
376 if not errors:
377 errors = range(_ERRMIN, _ERRMAX+1)
378 route = TinCanErrorRoute(self._tclass(source=self._template.body))
379 for error in errors:
380 if error < _ERRMIN or error > _ERRMAX:
381 raise TinCanError("{0}: bad #errors code".format(self._urlpath))
382 self._app.error(code=error, callback=route)
383
384 def _getclass(self):
360 pypath = os.path.normpath(os.path.join(self._fsroot, *self._subdir, self._python)) 385 pypath = os.path.normpath(os.path.join(self._fsroot, *self._subdir, self._python))
361 pycpath = pypath + 'c' 386 pycpath = pypath + 'c'
362 try: 387 try:
363 pyctime = os.stat(pycpath).st_mtime 388 pyctime = os.stat(pycpath).st_mtime
364 except OSError: 389 except OSError:
379 v = getattr(mod, i) 404 v = getattr(mod, i)
380 if issubclass(v, Page): 405 if issubclass(v, Page):
381 if self._class is not None: 406 if self._class is not None:
382 raise TinCanError("{0}: contains multiple Page classes", pypath) 407 raise TinCanError("{0}: contains multiple Page classes", pypath)
383 self._class = v 408 self._class = v
384 # Build body object (Chameleon template) 409 if self._class is None:
385 if self._header.template is not None: 410 raise TinCanError("{0}: contains no Page classes", pypath)
386 tpath = os.path.join(self._fsroot, *self._splitpath(self._header.template))
387 tfile = TemplateFile(tpath)
388 self._body = self._tclass(source=tfile.body)
389 else:
390 self._body = self._tclass(source=self._template.body)
391 self._body.prepare()
392 # Register this thing with Bottle
393 print("adding route:", self._origin) # debug
394 self._app.route(self._origin, methods, self)
395
396 def _splitpath(self, unsplit):
397 return _normpath(self._subdir, unsplit)
398 411
399 def _redirect(self): 412 def _redirect(self):
400 if self._header.forward in self._seen: 413 if self._header.forward in self._seen:
401 raise TinCanError("{0}: #forward loop".format(self._origin)) 414 raise TinCanError("{0}: #forward loop".format(self._origin))
402 self._seen.add(self._header.forward) 415 self._seen.add(self._header.forward)