Mercurial > cgi-bin > hgweb.cgi > tincan
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 |