comparison tincan.py @ 32:3382799f3905 draft header-includes

Refinements.
author David Barts <n5jrn@me.com>
date Mon, 27 May 2019 18:05:42 -0700
parents 443a0001d841
children cc975bf7a3fa
comparison
equal deleted inserted replaced
31:443a0001d841 32:3382799f3905
408 self._fspath = os.path.join(launcher.fsroot, *subdir, name + _TEXTEN) 408 self._fspath = os.path.join(launcher.fsroot, *subdir, name + _TEXTEN)
409 self._urlpath = self._urljoin(launcher.urlroot, *subdir, name + _TEXTEN) 409 self._urlpath = self._urljoin(launcher.urlroot, *subdir, name + _TEXTEN)
410 self._origin = self._urlpath 410 self._origin = self._urlpath
411 self._subdir = subdir 411 self._subdir = subdir
412 self._seen = set() 412 self._seen = set()
413 self._tclass = launcher.tclass
414 self._app = launcher.app 413 self._app = launcher.app
415 self._save_includes = launcher.debug 414 self._save_includes = launcher.debug
416 415
417 def launch(self): 416 def launch(self):
418 """ 417 """
466 tfile = TemplateFile(tpath) 465 tfile = TemplateFile(tpath)
467 except OSError as e: 466 except OSError as e:
468 raise TinCanError("{0}: invalid #template: {1!s}".format(self._urlpath, e)) from e 467 raise TinCanError("{0}: invalid #template: {1!s}".format(self._urlpath, e)) from e
469 except IndexError as e: 468 except IndexError as e:
470 raise TinCanError("{0}: invalid #template".format(self._urlpath)) from e 469 raise TinCanError("{0}: invalid #template".format(self._urlpath)) from e
471 self._body = self._tclass(source=tfile.body) 470 self._body = ChameleonTemplate(source=tfile.body)
472 try: 471 else:
473 includes = TemplateHeader(tfile.header).include 472 self._body = ChameleonTemplate(source=self._template.body)
474 except TemplateHeaderError as e:
475 raise TinCanError("{0}: {1!s}".format(self._fspath, e)) from e
476 ibase = rtpath[:-1]
477 else:
478 self._body = self._tclass(source=self._template.body)
479 includes = self._header.include
480 ibase = self._subdir
481 self._body.prepare() 473 self._body.prepare()
482 # Process includes 474 # Process includes
483 self._includes = {} 475 self._includes = {}
484 for include in includes: 476 for include in self._header.include:
485 try: 477 try:
486 include = _IncludedFile(include) 478 include = _IncludedFile(include)
487 except ValueError as e: 479 except ValueError as e:
488 raise TinCanError("{0}: bad #include: {1!s}".format(self._urlpath, e)) from e 480 raise TinCanError("{0}: bad #include: {1!s}".format(self._urlpath, e)) from e
489 if include.in_lib: 481 if include.in_lib:
490 fdir = os.path.join(self._fsroot, _WINF, "tlib") 482 fdir = os.path.join(self._fsroot, _WINF, "tlib")
491 else: 483 else:
492 fdir = os.path.join(self._fsroot, *ibase) 484 fdir = os.path.join(self._fsroot, *self._subdir)
493 try: 485 try:
494 tmpl = self._tclass(name=include.fname, lookup=[fdir]) 486 tmpl = ChameleonTemplate(name=include.fname, lookup=[fdir])
495 tmpl.prepare() 487 tmpl.prepare()
496 # tmpl.render() # is this needed?
497 except Exception as e: 488 except Exception as e:
498 raise TinCanError("{0}: bad #include: {1!s}".format(self._urlpath, e)) from e 489 raise TinCanError("{0}: bad #include: {1!s}".format(self._urlpath, e)) from e
499 self._includes[include.vname] = tmpl.tpl 490 self._includes[include.vname] = tmpl.tpl
500 # If this is an #errors page, register it as such. 491 # If this is an #errors page, register it as such.
501 if oheader.errors is not None: 492 if oheader.errors is not None:
520 errors = [ int(i) for i in rerrors.split() ] 511 errors = [ int(i) for i in rerrors.split() ]
521 except ValueError as e: 512 except ValueError as e:
522 raise TinCanError("{0}: bad #errors line".format(self._urlpath)) from e 513 raise TinCanError("{0}: bad #errors line".format(self._urlpath)) from e
523 if not errors: 514 if not errors:
524 errors = range(_ERRMIN, _ERRMAX+1) 515 errors = range(_ERRMIN, _ERRMAX+1)
525 route = _TinCanErrorRoute(self._tclass(source=self._template.body), 516 route = _TinCanErrorRoute(ChameleonTemplate(source=self._template.body),
526 self._includes, self._class) 517 self._includes, self._class)
527 for error in errors: 518 for error in errors:
528 if error < _ERRMIN or error > _ERRMAX: 519 if error < _ERRMIN or error > _ERRMAX:
529 raise TinCanError("{0}: bad #errors code".format(self._urlpath)) 520 raise TinCanError("{0}: bad #errors code".format(self._urlpath))
530 self._app.error_handler[error] = route # XXX 521 self._app.error_handler[error] = route # XXX
676 667
677 class _Launcher(object): 668 class _Launcher(object):
678 """ 669 """
679 Helper class for launching webapps. 670 Helper class for launching webapps.
680 """ 671 """
681 def __init__(self, fsroot, urlroot, tclass, logger): 672 def __init__(self, fsroot, urlroot, logger):
682 """ 673 """
683 Lightweight constructor. The real action happens in .launch() below. 674 Lightweight constructor. The real action happens in .launch() below.
684 """ 675 """
685 self.fsroot = fsroot 676 self.fsroot = fsroot
686 self.urlroot = urlroot 677 self.urlroot = urlroot
687 self.tclass = tclass
688 self.logger = logger 678 self.logger = logger
689 self.app = None 679 self.app = None
690 self.errors = 0 680 self.errors = 0
691 self.debug = False 681 self.debug = False
692 682
747 737
748 def _logger(message): 738 def _logger(message):
749 sys.stderr.write(message) 739 sys.stderr.write(message)
750 sys.stderr.write('\n') 740 sys.stderr.write('\n')
751 741
752 def launch(fsroot=None, urlroot='/', tclass=ChameleonTemplate, logger=_logger, debug=False): 742 def launch(fsroot=None, urlroot='/', logger=_logger, debug=False):
753 """ 743 """
754 Launch and return a TinCan webapp. Does not run the app; it is the 744 Launch and return a TinCan webapp. Does not run the app; it is the
755 caller's responsibility to call app.run() 745 caller's responsibility to call app.run()
756 """ 746 """
757 if fsroot is None: 747 if fsroot is None:
758 fsroot = os.getcwd() 748 fsroot = os.getcwd()
759 launcher = _Launcher(fsroot, urlroot, tclass, logger) 749 launcher = _Launcher(fsroot, urlroot, logger)
760 launcher.debug = debug 750 launcher.debug = debug
761 launcher.launch() 751 launcher.launch()
762 return launcher.app, launcher.errors 752 return launcher.app, launcher.errors
763 753
764 # XXX - We cannot implement a command-line launcher here; see the 754 # XXX - We cannot implement a command-line launcher here; see the