This file is indexed.

/usr/share/pyshared/albatross/template.py is in python-albatross 1.36-5.5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
#
# Copyright 2001 by Object Craft P/L, Melbourne, Australia.
#
# LICENCE - see LICENCE file distributed with this software for details.
#
# Templating core functionality
#
import re

from albatross.common import *

# Templates can test for a given level of template support.  Bump
# template_version when new tags or parsing features are added.
#
# History:
#   1 .. Albatross 1.20 and before
#   2 .. 1.30pre - added AnyTag features
template_version = 2

# Alternative scheme - list specific features - templates can test that
# a particular feature is available.
template_features = ()

# The template file parser treats HTML files as plain text with
# embedded template tags.  In parsing the file a tag tree is
# constructed.  Tags are either empty or enclosing.


# Plain text from the template file is managed by a Text object.  This
# allows the template interpreter to treat text no differently from a
# tag.

class Text:

    name = None

    def __init__(self, text):
        self.text = text

    def __repr__(self):
        return 'Text(%s)' % self.text

    def to_html(self, ctx):
        ctx.write_content(self.text)


# All tags in the toolkit and application are implemented by
# subclassing either EmptyTag or EnclosingTag.  Each of these classes
# inherit from Tag.

class Tag:

    '''Functionality common to all HTML template tags.
    '''

    def __init__(self, ctx, filename, line_num, attribs):
        '''Store where the tag was defined for execution trace
        generation
        '''
        self.filename = filename
        self.line_num = line_num
        self.attribs = attribs
        self.attrib_order = None

    def __repr__(self):
        parts = []
        parts.append('<')
        parts.append(self.name)
        for name in self.attrib_order:
            value = self.attribs[name]
            if value is not None:
                parts.append(' %s="%s"' % (name, value))
            else:
                parts.append(' %s' % name)
        parts.append('>')
        return ''.join(parts)

    def raise_error(self, msg):
        raise ApplicationError('%s:%s: %s' % \
                               (self.filename, self.line_num, msg))

    def has_attrib(self, name):
        '''Was the named attribute named with the tag
        '''
        return name in self.attribs

    def assert_has_attrib(self, name):
        if name not in self.attribs:
            self.raise_error('missing "%s" attribute' % name)

    def assert_any_attrib(self, *attrs):
        """ Check that the tag has at least one of the attributes """
        for attr in attrs:
            if self.has_attrib(attr):
                return
        if len(attrs) == 1:
            self.raise_error('missing %s attribute' % repr(attrs[0]))
        else:
            attr_list = ', '.join([repr(attr) for attr in attrs[:-1]])
            self.raise_error('missing %s or %s attribute' %\
                             (attr_list, repr(attrs[-1])))

    def assert_only_attrib(self, *attrs):
        """ Check that the tag only has the listed attributes """
        for name in self.attribs.keys():
            if name not in attrs:
                self.raise_error('"%s" attribute not support by this tag' % name)

    def get_attrib(self, name, default = None):
        '''Return the value of the named attribute
        '''
        return self.attribs.get(name, default)

    def get_expr_attrib(self, ctx, name, default=None):
        """
        If /name/expr version of attribute exists, fetch it, evaluate
        and return the result, otherwise fetch the value of /name/.
        """
        if name + 'expr' in self.attribs:
            return self.eval_attrib(ctx, name + 'expr')
        else:
            return self.attribs.get(name, default)

    def get_bool_attrib(self, ctx, name, default=False):
        """
        If /name/bool version of attribute exists, fetch it, evaluate
        it in a boolean context and return the result, otherwise return
        whether /name/ exists.
        """
        if name + 'bool' in self.attribs:
            return bool(self.eval_attrib(ctx, name + 'bool'))
        else:
            return name in self.attribs

    def set_attrib_order(self, order):
        self.attrib_order = order

    def set_attrib(self, name, value):
        '''Set the value of the named attribute
        '''
        self.attribs[name] = value
        if name not in self.attrib_order:
            self.attrib_order.append(name)

    def attrib_items(self):
        return self.attribs.items()

    def write_attribs_except(self, ctx, *exclude):
        for name in self.attrib_order:
            if name in exclude:
                continue
            if name.endswith('bool'):
                if self.eval_attrib(ctx, name):
                    ctx.write_content(' %s' % name[:-len('bool')])
            else:
                if name[:-4] and name.endswith('expr'):
                    value = self.eval_attrib(ctx, name)
                    name = name[:-len('expr')]
                else:
                    value = self.attribs[name]
                if value is not None:
                    ctx.write_content(' %s="%s"' % (name, value))
                else:
                    ctx.write_content(' %s' % name)

    def eval_attrib(self, ctx, attr, kind = 'eval'):
        code_attr = 'co_' + attr
        try:
            code_obj = getattr(self, code_attr)
        except AttributeError:
            code_obj = compile(self.get_attrib(attr), '<albatross>', kind)
            setattr(self, code_attr, code_obj)
        return ctx.eval_expr(code_obj)


# Tags such as <al-input>, <al-let>, <al-usearg> do not enclose
# content.  These tags just use the information in their attributes to
# generate output.
#
# When you subclass the EmptyTag class you must supply a name class
# attribute and you should almost certainly override the to_html()
# method.
#
# class HR(template.EmptyTag):
#     name = 'al-hr'
#
#     def to_html(self, ctx):
#         ctx.write_content('<hr noshade>')
#
# The name attribute allows the code which interprets the parsed
# template to identify each tag.  It is also used by the parser to
# locate which class to instantiate when it finds a tag of the same
# name in the template file.

class EmptyTag(Tag):

    '''All tags which do not enclose content inherit from this class
    '''

    def has_content(self):
        return 0

    def to_html(self, ctx):
        pass


# Content objects are the basic building block of the parsed HTML
# template.  Converting a Content object to HTML simply converts each
# item in the object to HTML.  All content enclosing tags use Content
# objects to store their content and then use the special tag logic to
# control when and how often the content should be sent as output.

class Content:

    '''Manage a list of content items.
    '''

    def __init__(self):
        self.items = []

    def __repr__(self):
        return 'Content(%s)' % self.items

    def __len__(self):
        return len(self.items)

    def append(self, item):
        self.items.append(item)

    def to_html(self, ctx):
        for item in self.items:
            item.to_html(ctx)

# Tags such as <al-in>, <al-form>, <al-tree>, <al-expand> do
# enclose content.
#
# When you subclass the EnclosingTag class you must supply a name
# class attribute and you should almost certainly override the
# to_html() method.  For example, the following is very simple if:
#
# class If(template.ContentTag):
#     name = 'al-if'
#
#     def __init__(self, ctx, filename, line_num, attribs):
#         template.ContentTag.__init__(self, ctx, filename, line_num, attribs)
#         if not self.has_attrib('expr'):
#             self.raise_error('missing "expr" attribute')
#         self.expr = compile(self.get_attrib('expr'), '<albatross>', 'eval')
#
#     def to_html(self, ctx):
#         if ctx.eval_expr(self.expr):
#             template.ContentTag.to_html(self, ctx)

class EnclosingTag(Tag):

    '''All tags which enclose content inherit from this class
    '''

    def __init__(self, ctx, filename, line_num, attribs):
        Tag.__init__(self, ctx, filename, line_num, attribs)
        self.content = Content()

    def __repr__(self):
        return Tag.__repr__(self) + repr(self.content) + '</%s>' % self.name

    def has_content(self):
        return 1

    def append(self, item):
        self.content.append(item)

    def to_html(self, ctx):
        self.content.to_html(ctx)

class AnyTag(EnclosingTag):
    empty_tags = {
        'area': None, 'base': None, 'basefont': None, 'br': None, 
        'col': None, 'frame': None, 'hr': None, 'img': None, 
        'input': None, 'isindex': None, 'link': None, 'meta': None, 
        'param': None,
    }

    def __init__(self, ctx, filename, line_num, name, attribs):
        EnclosingTag.__init__(self, ctx, filename, line_num, attribs)
        self.name = name

    def has_content(self):
        return self.name[3:] not in self.empty_tags

    def to_html(self, ctx):
        name = self.name[3:]
        ctx.write_content('<%s' % name)
        self.write_attribs_except(ctx)
        ctx.write_content('>')
        if self.has_content():
            EnclosingTag.to_html(self, ctx)
            ctx.write_content('</%s>' % name)


# A Template object contains the parsed HTML content of a single
# template file.  Loading a template parses the HTML and compiles the
# expressions within the file.  The execution phase happens later once
# the application has established an execution context.
#
# A tag "manager" is passed in which resolves the tag name to a Python
# class which implements that tag.  This allows the application to
# extend the standard tag set without changing the toolkit.

# Parsing works by splitting the file into a stream of text, tag,
# text, tag, ...  The current parent object for content is maintained
# on a stack, each time a new content enclosing tag is encountered,
# the current parent is saved and all new content is directed to the
# new parent.  When the close tag is encountered the old parent is
# popped off the stack.

# Locate tags; remember start, attribs, end
_sre_dblquote_nogrp = r'"(?:[^"\\]*(?:\\.[^"\\]*)*)"'   # eg, "hello \"bill\""
_sre_sglquote_nogrp = r"'(?:[^'\\]*(?:\\.[^'\\]*)*)'"   # eg, 'sam\'s ball'
_sre_attr = r'(?:' + \
    r'\s+\w+=' + _sre_dblquote_nogrp + '|' + \
    r'\s+\w+=' + _sre_sglquote_nogrp + '|' + \
    r'\s+\w+' + ')'                                     # eg, attr="value"
_sre_attrs = r'(' + _sre_attr + r'*)'                   # eg, a1="v1" a2="v2"
_sre_tagname = r'(/?alx?-\w+)'                          # eg, al-value
_re_tagname = re.compile('^'+_sre_tagname+'$', re.I)
_sre_tag = r'<'+_sre_tagname+_sre_attrs+r'(\s*/?>)'     # a full albatross tag
_re_tag = re.compile(_sre_tag, re.I|re.M|re.S)

_re_leading = re.compile(r'^\s+')

# Extract attributes
_sre_dblquote_grp = r'"([^"\\]*(?:\\.[^"\\]*)*)"'
_sre_sglquote_grp = r"'([^'\\]*(?:\\.[^'\\]*)*)'"
_sre_attr_grp = r'(\w+)=(?:'+_sre_dblquote_grp+'|'+_sre_sglquote_grp+')|(\w+)'
_re_attrib = re.compile(_sre_attr_grp, re.I|re.M)

_re_dequote = re.compile(r'\\(.)')


def check_tagname(name):
    if not _re_tagname.match(name):
        raise ApplicationError('Invalid tag name %r' % name)

class Template:

    '''Manage a single HTML template file
    '''

    def __init__(self, ctx, filename, text):
        '''The ctx argument is is used to resolve tag names to tag
        classes.  filename is to identify where the template text came
        from.

        The the file identified by filename is never referenced to
        allow external code to implement caching schemes.  It also
        allows you to do things like this:

        t = Template(tags, "<cache>",
        """<al-for iter="i" expr="range(20)">
          <al-value expr="i.value">
        </al-for>""")
        '''
        TAG_TEXT = 0
        TAG_NAME = 1
        TAG_ATTRIBS = 2
        TAG_CLOSE = 3
        WHITE_ALL = 'all'
        WHITE_STRIP = 'strip'
        WHITE_INDENT = 'indent'
        WHITE_NEWLINE = 'newline'

        state = TAG_TEXT
        white_space = WHITE_STRIP
        self.content = Content()
        parent_stack = []
        parent = self.content
        line_num = 1
        for part in _re_tag.split(text):
            if state == TAG_TEXT:
                text = part
                if text:
                    if white_space == WHITE_STRIP:
                        if text.startswith('\n'):
                            text = _re_leading.sub('', text)
                    elif white_space == WHITE_INDENT:
                        if text.startswith('\n'):
                            text = text[1:]
                    elif white_space == WHITE_NEWLINE:
                        text = '\n'
                if text:
                    parent.append(Text(text))
                white_space = WHITE_STRIP
                state = TAG_NAME
            elif state == TAG_NAME:
                name = part.lower()
                if name[0] == '/':
                    # close tag - pop parent
                    name = name[1:]
                    if not parent_stack:
                        raise ApplicationError('%s:%s: "%s"; unexpected "%s" end tag' % (filename, line_num, part, name))
                    if parent.name != name:
                        raise ApplicationError('%s:%s: "%s"; expected "%s" end tag' % (filename, line_num, part, parent.name))
                    parent = parent_stack[-1]
                    del parent_stack[-1]
                    is_open = 0
                else:
                    # open tag - find class
                    tagclass = ctx.get_tagclass(name)
                    if not tagclass:
                        if name.startswith('al-'):
                            tagclass = AnyTag
                            tagname = name
                        else:
                            raise ApplicationError('%s:%s: undefined tag "%s"'%\
                                                   (filename, line_num, name))
                    is_open = 1
                state = TAG_ATTRIBS
            elif state == TAG_ATTRIBS:
                bits = _re_attrib.split(part)
                attribs = {}
                attrib_order = []
                offset = 0
                while 1:
                    attrbits = bits[offset: offset + 5]
                    if len(attrbits) < 5:
                        break
                    offset = offset + 5
                    white, name1, value1, value2, name2 = attrbits
                    if name1:
                        name = name1.lower()
                        if value1 is not None:
                            value = _re_dequote.sub(r'\1', value1)
                        else:
                            value = _re_dequote.sub(r'\1', value2)
                    else:
                        name = name2.lower()
                        value = None
                    if name == 'whitespace':
                        if value not in (WHITE_ALL, WHITE_STRIP, WHITE_INDENT,
                                         WHITE_NEWLINE, None):
                            raise ApplicationError('%s:%s: illegal whitespace value "%s"' % \
                                                   (filename, line_num, value))
                        white_space = value
                    else:
                        attribs[name] = value
                        attrib_order.append(name)
                if is_open:
                    if tagclass is AnyTag:
                        tag = tagclass(ctx, filename, line_num, tagname, attribs)
                    else:
                        tag = tagclass(ctx, filename, line_num, attribs)
                    tag.set_attrib_order(attrib_order)
                    parent.append(tag)
                    if tag.has_content():
                        parent_stack.append(parent)
                        parent = tag
                state = TAG_CLOSE
            elif state == TAG_CLOSE:
                if part.endswith('/>'):
                    if tag.has_content():
                        parent = parent_stack[-1]
                        del parent_stack[-1]
                else:
                    pass
                state = TAG_TEXT
            line_num += part.count('\n')
        if state not in (TAG_TEXT, TAG_NAME):
            raise ApplicationError('%s:%s: incomplete tag definition' % \
                                   (filename, line_num))
        if parent_stack:
            raise ApplicationError('%s:%s: missing close tag for "%s"' % \
                                   (filename, parent.line_num, parent.name))

    def __repr__(self):
        return 'Template(%s)' % self.content

    def to_html(self, ctx):
        '''Execute template within an execution context.
        '''
        self.content.to_html(ctx)


if __name__ == '__main__':
    import sys
    from albatross import context
    ctx = context.SimpleContext('../test')
    t = Template(ctx, '<ether>', '''
<al-lookup name="xlat">
 <al-item expr="0">Zero</al-item>
 <al-item expr="1">One</al-item>
 <al-item expr="2">Two</al-item>
 Many</al-lookup>
<al-for iter="i" expr="range(12)">
 <al-value expr="i.value()" lookup="xlat" whitespace>
</al-for>
''')
    t.to_html(ctx)
    ctx.flush_content()