Beispiel #1
0
    def renderwob(self, md):
        """RENDER WithOutBatch"""
        expr = self.expr
        name = self.__name__
        if expr is None:
            sequence = md[name]
            cache = {name: sequence}
        else:
            sequence = expr(md)
            cache = None

        if not sequence:
            if self.elses:
                return render_blocks(self.elses, md)
            return ''

        if isinstance(sequence, str):
            raise ValueError('Strings are not allowed as input to the in tag.')

        # Turn iterable like dict.keys() into a list.
        sequence = list(sequence)
        if cache is not None:
            cache[name] = sequence

        section = self.section
        mapping = self.mapping
        no_push_item = self.no_push_item

        if self.sort_expr is not None:
            self.sort = self.sort_expr.eval(md)
            sequence = self.sort_sequence(sequence, md)
        elif self.sort is not None:
            sequence = self.sort_sequence(sequence, md)

        if self.reverse_expr is not None and self.reverse_expr.eval(md):
            sequence = self.reverse_sequence(sequence)
        elif self.reverse is not None:
            sequence = self.reverse_sequence(sequence)

        prefix = self.args.get('prefix')
        vars = sequence_variables(sequence, alt_prefix=prefix)
        kw = vars.data
        pkw = add_with_prefix(kw, 'sequence', prefix)
        for k, v in list(kw.items()):
            pkw[k] = v
        kw['mapping'] = mapping

        l_ = len(sequence)
        last = l_ - 1

        push = md._push
        pop = md._pop
        render = render_blocks

        if cache:
            push(cache)
        push(vars)
        try:
            result = []
            append = result.append
            guarded_getitem = getattr(md, 'guarded_getitem', None)
            for index in range(l_):
                if index == last:
                    pkw['sequence-end'] = 1
                if guarded_getitem is not None:
                    try:
                        client = guarded_getitem(sequence, index)
                    except ValidationError as vv:
                        if ('skip_unauthorized' in self.args
                                and self.args['skip_unauthorized']):
                            if index == 1:
                                pkw['sequence-start'] = 0
                            continue
                        raise ValidationError('(item %s): %s' % (index, vv),
                                              sys.exc_info()[2])
                else:
                    client = sequence[index]

                pkw['sequence-index'] = index
                t = type(client)
                if t is TupleType and len(client) == 2:
                    client = client[1]

                if no_push_item:
                    pushed = 0
                elif mapping:
                    pushed = 1
                    push(client)
                elif t in StringTypes:
                    pushed = 0
                else:
                    pushed = 1
                    push(InstanceDict(client, md))

                try:
                    append(render(section, md))
                finally:
                    if pushed:
                        pop()
                if index == 0:
                    pkw['sequence-start'] = 0

            result = join_unicode(result)

        finally:
            if cache:
                pop()
            pop()

        return result
Beispiel #2
0
def tpRenderTABLE(
    self,
    id,
    root_url,
    url,
    state,
    substate,
    diff,
    data,
    colspan,
    section,
    md,
    treeData,
    level=0,
    args=None,
    try_call_attr=try_call_attr,
):
    "Render a tree as a table"

    have_arg = args.has_key
    exp = 0

    if level >= 0:
        urlattr = args['url']
        if urlattr and hasattr(self, urlattr):
            tpUrl = try_call_attr(self, urlattr)
            url = (url and ('%s/%s' % (url, tpUrl))) or tpUrl
            root_url = root_url or tpUrl

    ptreeData = add_with_prefix(treeData, 'tree', args.get('prefix'))
    ptreeData['tree-item-url'] = url
    ptreeData['tree-level'] = level
    ptreeData['tree-item-expanded'] = 0
    idattr = args['id']

    output = data.append

    items = None
    if (have_arg('assume_children') and args['assume_children']
            and substate is not state):
        # We should not compute children unless we have to.
        # See if we've been asked to expand our children.
        for i in range(len(substate)):
            sub = substate[i]
            if sub[0] == id:
                exp = i + 1
                break
        if not exp: items = 1

    get = md.guarded_getattr
    if get is None:
        get = getattr

    if items is None:
        if have_arg('branches') and hasattr(self, args['branches']):
            items = get(self, args['branches'])
            items = items()
        elif have_arg('branches_expr'):
            items = args['branches_expr'](md)

        if not items and have_arg('leaves'): items = 1

    if items and items != 1:

        getitem = getattr(md, 'guarded_getitem', None)
        if getitem is not None:
            unauth = []
            for index in range(len(items)):
                try:
                    getitem(items, index)
                except ValidationError:
                    unauth.append(index)
            if unauth:
                if have_arg('skip_unauthorized') and args['skip_unauthorized']:
                    items = list(items)
                    unauth.reverse()
                    for index in unauth:
                        del items[index]
                else:
                    raise ValidationError, unauth

        if have_arg('sort'):
            # Faster/less mem in-place sort
            if type(items) == type(()):
                items = list(items)
            sort = args['sort']
            size = range(len(items))
            for i in size:
                v = items[i]
                k = getattr(v, sort)
                try:
                    k = k()
                except:
                    pass
                items[i] = (k, v)
            items.sort()
            for i in size:
                items[i] = items[i][1]

        if have_arg('reverse'):
            items = list(items)  # Copy the list
            items.reverse()

    diff.append(id)

    _td_colspan = '<td colspan="%s" style="white-space: nowrap"></td>'
    _td_single = '<td width="16" style="white-space: nowrap"></td>'

    sub = None
    if substate is state:
        output('<table cellspacing="0">\n')
        sub = substate[0]
        exp = items
    else:
        # Add prefix
        output('<tr>\n')

        # Add +/- icon
        if items:
            if level:
                if level > 3: output(_td_colspan % (level - 1))
                elif level > 1: output(_td_single * (level - 1))
                output(_td_single)
                output('\n')
            output('<td width="16" valign="top" style="white-space: nowrap">')
            for i in range(len(substate)):
                sub = substate[i]
                if sub[0] == id:
                    exp = i + 1
                    break

            ####################################
            # Mostly inline encode_seq for speed
            s = compress(json.dumps(diff))
            if len(s) > 57:
                s = encode_str(s)
            else:
                s = b2a_base64(s)[:-1]
                l = s.find('=')
                if l >= 0:
                    s = s[:l]
            s = s.translate(tplus)
            ####################################

            script = md['BASEPATH1']

            # Propagate extra args through tree.
            if args.has_key('urlparam'):
                param = args['urlparam']
                param = "%s&" % param
            else:
                param = ""

            if exp:
                ptreeData['tree-item-expanded'] = 1
                output('<a name="%s" href="%s?%stree-c=%s#%s">'
                       '<img src="%s/p_/mi" alt="-" border="0" /></a>' %
                       (id, root_url, param, s, id, script))
            else:
                output('<a name="%s" href="%s?%stree-e=%s#%s">'
                       '<img src="%s/p_/pl" alt="+" border="0" /></a>' %
                       (id, root_url, param, s, id, script))
            output('</td>\n')

        else:
            if level > 2: output(_td_colspan % level)
            elif level > 0: output(_td_single * level)
            output(_td_single)
            output('\n')

        # add item text
        dataspan = colspan - level
        output('<td%s%s valign="top" align="left">' %
               ((dataspan > 1 and (' colspan="%s"' % dataspan) or ''),
                (have_arg('nowrap') and args['nowrap']
                 and ' style="white-space: nowrap"' or '')))
        output(render_blocks(section, md))
        output('</td>\n</tr>\n')

    if exp:

        level = level + 1
        dataspan = colspan - level
        if level > 2: h = _td_colspan % level
        elif level > 0: h = _td_single * level
        else: h = ''

        if have_arg('header'):
            doc = args['header']
            if md.has_key(doc): doc = md.getitem(doc, 0)
            else: doc = None
            if doc is not None:
                output(
                    doc(
                        None,
                        md,
                        standard_html_header=(
                            '<tr>%s'
                            '<td width="16" style="white-space: nowrap"></td>'
                            '<td%s valign="top">' %
                            (h, (dataspan > 1 and
                                 (' colspan="%s"' % dataspan) or ''))),
                        standard_html_footer='</td></tr>',
                    ))

        if items == 1:
            # leaves
            if have_arg('leaves'):
                doc = args['leaves']
                if md.has_key(doc): doc = md.getitem(doc, 0)
                else: doc = None
                if doc is not None:
                    treeData['-tree-substate-'] = sub
                    ptreeData['tree-level'] = level
                    md._push(treeData)
                    try:
                        output(
                            doc(
                                None,
                                md,
                                standard_html_header=
                                ('<tr>%s'
                                 '<td width="16" style="white-space: nowrap"></td>'
                                 '<td%s valign="top">' %
                                 (h, (dataspan > 1 and
                                      (' colspan="%s"' % dataspan) or ''))),
                                standard_html_footer='</td></tr>',
                            ))
                    finally:
                        md._pop(1)
        elif have_arg('expand'):
            doc = args['expand']
            if md.has_key(doc): doc = md.getitem(doc, 0)
            else: doc = None
            if doc is not None:
                treeData['-tree-substate-'] = sub
                ptreeData['tree-level'] = level
                md._push(treeData)
                try:
                    output(
                        doc(
                            None,
                            md,
                            standard_html_header=
                            ('<tr>%s<td width="16" style="white-space: nowrap"></td>'
                             '<td%s valign="top">' %
                             (h, (dataspan > 1 and
                                  (' colspan="%s"' % dataspan) or ''))),
                            standard_html_footer='</td></tr>',
                        ))
                finally:
                    md._pop(1)
        else:
            __traceback_info__ = sub, args, state, substate
            ids = {}
            for item in items:
                if hasattr(item, idattr):
                    id = try_call_attr(item, idattr)
                elif hasattr(item, '_p_oid'):
                    id = oid(item)
                else:
                    id = pyid(item)
                if len(sub) == 1: sub.append([])
                substate = sub[1]
                ids[id] = 1
                md._push(InstanceDict(item, md))
                try:
                    data = tpRenderTABLE(item, id, root_url, url, state,
                                         substate, diff, data, colspan,
                                         section, md, treeData, level, args)
                finally:
                    md._pop()
                if not sub[1]: del sub[1]

            ids = ids.has_key
            for i in range(len(substate) - 1, -1):
                if not ids(substate[i][0]): del substate[i]

        if have_arg('footer'):
            doc = args['footer']
            if md.has_key(doc): doc = md.getitem(doc, 0)
            else: doc = None
            if doc is not None:
                output(
                    doc(
                        None,
                        md,
                        standard_html_header=
                        ('<tr>%s<td width="16" style="white-space: nowrap"></td>'
                         '<td%s valign="top">' %
                         (h, (dataspan > 1 and
                              (' colspan="%s"' % dataspan) or ''))),
                        standard_html_footer='</td></tr>',
                    ))

    del diff[-1]
    if not diff: output('</table>\n')

    return data
Beispiel #3
0
    def renderwb(self, md):
        expr = self.expr
        name = self.__name__
        if expr is None:
            sequence = md[name]
            cache = {name: sequence}
        else:
            sequence = expr(md)
            cache = None

        if not sequence:
            if self.elses:
                return render_blocks(self.elses, md)
            return ''

        if isinstance(sequence, str):
            raise ValueError('Strings are not allowed as input to the in tag.')

        # Turn iterable like dict.keys() into a list.
        sequence = list(sequence)
        if cache is not None:
            cache[name] = sequence

        section = self.section
        params = self.args

        mapping = self.mapping
        no_push_item = self.no_push_item

        if self.sort_expr is not None:
            self.sort = self.sort_expr.eval(md)
            sequence = self.sort_sequence(sequence, md)
        elif self.sort is not None:
            sequence = self.sort_sequence(sequence, md)

        if self.reverse_expr is not None and self.reverse_expr.eval(md):
            sequence = self.reverse_sequence(sequence)
        elif self.reverse is not None:
            sequence = self.reverse_sequence(sequence)

        next = previous = 0
        try:
            start = int_param(params, md, 'start', 0)
        except Exception:
            start = 1
        end = int_param(params, md, 'end', 0)
        size = int_param(params, md, 'size', 0)
        overlap = int_param(params, md, 'overlap', 0)
        orphan = int_param(params, md, 'orphan', '0')
        start, end, sz = opt(start, end, size, orphan, sequence)
        if 'next' in params:
            next = 1
        if 'previous' in params:
            previous = 1

        last = end - 1
        first = start - 1

        try:
            query_string = md['QUERY_STRING']
        except Exception:
            query_string = ''
        prefix = params.get('prefix')
        vars = sequence_variables(sequence, '?' + query_string,
                                  self.start_name_re, prefix)
        kw = vars.data
        pkw = add_with_prefix(kw, 'sequence', prefix)
        for k, v in list(kw.items()):
            pkw[k] = v
        pkw['sequence-step-size'] = sz
        pkw['sequence-step-overlap'] = overlap
        pkw['sequence-step-start'] = start
        pkw['sequence-step-end'] = end
        pkw['sequence-step-start-index'] = start - 1
        pkw['sequence-step-end-index'] = end - 1
        pkw['sequence-step-orphan'] = orphan

        kw['mapping'] = mapping

        push = md._push
        pop = md._pop
        render = render_blocks

        if cache:
            push(cache)
        push(vars)
        try:
            if previous:
                if first > 0:
                    pstart, pend, psize = opt(0, first + overlap, sz, orphan,
                                              sequence)
                    pkw['previous-sequence'] = 1
                    pkw['previous-sequence-start-index'] = pstart - 1
                    pkw['previous-sequence-end-index'] = pend - 1
                    pkw['previous-sequence-size'] = pend + 1 - pstart
                    result = render(section, md)

                elif self.elses:
                    result = render(self.elses, md)
                else:
                    result = ''
            elif next:
                try:
                    # The following line is a sneaky way to test whether
                    # there are more items, without actually
                    # computing a length:
                    sequence[end]
                except IndexError:
                    if self.elses:
                        result = render(self.elses, md)
                    else:
                        result = ''
                else:
                    pstart, pend, psize = opt(end + 1 - overlap, 0, sz, orphan,
                                              sequence)
                    pkw['next-sequence'] = 1
                    pkw['next-sequence-start-index'] = pstart - 1
                    pkw['next-sequence-end-index'] = pend - 1
                    pkw['next-sequence-size'] = pend + 1 - pstart
                    result = render(section, md)
            else:
                result = []
                append = result.append
                guarded_getitem = getattr(md, 'guarded_getitem', None)
                for index in range(first, end):
                    # preset
                    pkw['previous-sequence'] = 0
                    # now more often defined then previously
                    pkw['next-sequence'] = 0
                    #
                    if index == first or index == last:
                        # provide batching information
                        if first > 0:
                            pstart, pend, psize = opt(0, first + overlap, sz,
                                                      orphan, sequence)
                            if index == first:
                                pkw['previous-sequence'] = 1
                            pkw['previous-sequence-start-index'] = pstart - 1
                            pkw['previous-sequence-end-index'] = pend - 1
                            pkw['previous-sequence-size'] = pend + 1 - pstart
                        try:
                            # The following line is a sneaky way to
                            # test whether there are more items,
                            # without actually computing a length:
                            sequence[end]
                            pstart, pend, psize = opt(end + 1 - overlap, 0, sz,
                                                      orphan, sequence)
                            if index == last:
                                pkw['next-sequence'] = 1
                            pkw['next-sequence-start-index'] = pstart - 1
                            pkw['next-sequence-end-index'] = pend - 1
                            pkw['next-sequence-size'] = pend + 1 - pstart
                        except Exception:
                            pass

                    if index == last:
                        pkw['sequence-end'] = 1

                    if guarded_getitem is not None:
                        try:
                            client = guarded_getitem(sequence, index)
                        except ValidationError as vv:
                            if ('skip_unauthorized' in params
                                    and params['skip_unauthorized']):
                                if index == first:
                                    pkw['sequence-start'] = 0
                                continue
                            raise ValidationError(
                                '(item %s): %s' % (index, vv),
                                sys.exc_info()[2])
                    else:
                        client = sequence[index]

                    pkw['sequence-index'] = index
                    t = type(client)
                    if t is TupleType and len(client) == 2:
                        client = client[1]

                    if no_push_item:
                        pushed = 0
                    elif mapping:
                        pushed = 1
                        push(client)
                    elif t in StringTypes:
                        pushed = 0
                    else:
                        pushed = 1
                        push(InstanceDict(client, md))

                    try:
                        append(render(section, md))
                    finally:
                        if pushed:
                            pop()

                    if index == first:
                        pkw['sequence-start'] = 0

                result = join_unicode(result)

        finally:
            if cache:
                pop()
            pop()

        return result
Beispiel #4
0
def tpRenderTABLE(
    self,
    id,
    root_url,
    url,
    state,
    substate,
    diff,
    data,
    colspan,
    section,
    md,
    treeData,
    level=0,
    args=None,
    try_call_attr=try_call_attr,
    encoding=None,
):
    "Render a tree as a table"
    encoding = encoding or 'latin-1'
    exp = 0

    if level >= 0:
        urlattr = args['url']
        if urlattr and hasattr(self, urlattr):
            tpUrl = try_call_attr(self, urlattr)
            url = (url and ('%s/%s' % (url, tpUrl))) or tpUrl
            root_url = root_url or tpUrl

    ptreeData = add_with_prefix(treeData, 'tree', args.get('prefix'))
    ptreeData['tree-item-url'] = url
    ptreeData['tree-level'] = level
    ptreeData['tree-item-expanded'] = 0

    output = data.append

    items = None
    if ('assume_children' in args and args['assume_children']
            and substate is not state):
        # We should not compute children unless we have to.
        # See if we've been asked to expand our children.
        for i in range(len(substate)):
            sub = substate[i]
            if sub[0] == id:
                exp = i + 1
                break
        if not exp:
            items = 1

    get = md.guarded_getattr
    if get is None:
        get = getattr

    if items is None:
        if 'branches' in args and hasattr(self, args['branches']):
            items = get(self, args['branches'])
            items = items()
        elif 'branches_expr' in args:
            items = args['branches_expr'](md)

        if not items and 'leaves' in args:
            items = 1

    if items and items != 1:

        getitem = getattr(md, 'guarded_getitem', None)
        if getitem is not None:
            unauth = []
            for index in range(len(items)):
                try:
                    getitem(items, index)
                except ValidationError:
                    unauth.append(index)
            if unauth:
                if 'skip_unauthorized' in args and args['skip_unauthorized']:
                    items = list(items)
                    unauth.reverse()
                    for index in unauth:
                        del items[index]
                else:
                    raise ValidationError(unauth)

        if 'sort' in args:
            # Faster/less mem in-place sort
            if isinstance(items, tuple):
                items = list(items)
            sort = args['sort']
            size = range(len(items))
            for i in size:
                v = items[i]
                k = getattr(v, sort)
                try:
                    k = k()
                except Exception:
                    pass
                items[i] = (k, v)
            items.sort()
            for i in size:
                items[i] = items[i][1]

        if 'reverse' in args:
            items = list(items)  # Copy the list
            items.reverse()

    if isinstance(id, six.binary_type):
        diff.append(id.decode(encoding))
    else:
        diff.append(id)

    _td_colspan = '<td colspan="%s" style="white-space: nowrap"></td>'
    _td_single = '<td width="16" style="white-space: nowrap"></td>'

    sub = None
    if substate is state:
        output('<table cellspacing="0">\n')
        sub = substate[0]
        exp = items
    else:
        # Add prefix
        output('<tr>\n')

        # Add +/- icon
        if items:
            if level:
                if level > 3:
                    output(_td_colspan % (level - 1))
                elif level > 1:
                    output(_td_single * (level - 1))
                output(_td_single)
                output('\n')
            output('<td width="16" valign="top" style="white-space: nowrap">')
            for i in range(len(substate)):
                sub = substate[i]
                if sub[0] == id:
                    exp = i + 1
                    break

            s = encode_str(compress(json.dumps(diff)))  # bytes in ASCII enc.

            # For rendering the encoded state string in a URL under Python 3,
            # we must lose the "b" prefix by decoding
            if six.PY3:
                s = s.decode('ASCII')

            # Propagate extra args through tree.
            if 'urlparam' in args:
                param = args['urlparam']
                param = "%s&" % param
            else:
                param = ""

            if exp:
                ptreeData['tree-item-expanded'] = 1
                icon = ('<i title="Collapse..."'
                        ' class="fas fa-caret-down text-muted"></i>')
                output('<a name="%s" href="%s?%stree-c=%s#%s">%s</a>' %
                       (id, root_url, param, s, id, icon))
            else:
                icon = ('<i title="Expand..."'
                        ' class="fas fa-caret-right text-muted"></i>')
                output('<a name="%s" href="%s?%stree-e=%s#%s">%s</a>' %
                       (id, root_url, param, s, id, icon))
            output('</td>\n')

        else:
            if level > 2:
                output(_td_colspan % level)
            elif level > 0:
                output(_td_single * level)
            output(_td_single)
            output('\n')

        # add item text
        dataspan = colspan - level
        output('<td%s%s valign="top" align="left">' %
               ((dataspan > 1 and (' colspan="%s"' % dataspan) or ''),
                ('nowrap' in args and args['nowrap']
                 and ' style="white-space: nowrap"' or '')))
        output(render_blocks(section, md, encoding=encoding))
        output('</td>\n</tr>\n')

    if exp:
        level = level + 1
        dataspan = colspan - level
        if level > 2:
            h = _td_colspan % level
        elif level > 0:
            h = _td_single * level
        else:
            h = ''

        if 'header' in args:
            doc = args['header']
            if doc in md:
                doc = md.getitem(doc, 0)
            else:
                doc = None
            if doc is not None:
                output(
                    doc(
                        None,
                        md,
                        standard_html_header=(
                            '<tr>%s'
                            '<td width="16" style="white-space: nowrap"></td>'
                            '<td%s valign="top">' %
                            (h, (dataspan > 1 and
                                 (' colspan="%s"' % dataspan) or ''))),
                        standard_html_footer='</td></tr>',
                    ))

        if items == 1:
            # leaves
            if 'leaves' in args:
                doc = args['leaves']
                if doc in md:
                    doc = md.getitem(doc, 0)
                else:
                    doc = None
                if doc is not None:
                    treeData['-tree-substate-'] = sub
                    ptreeData['tree-level'] = level
                    md._push(treeData)
                    try:
                        output(
                            doc(
                                None,
                                md,
                                standard_html_header=
                                ('<tr>%s<td '
                                 'width="16" style="white-space: nowrap"></td>'
                                 '<td%s valign="top">' %
                                 (h, (dataspan > 1 and
                                      (' colspan="%s"' % dataspan) or ''))),
                                standard_html_footer='</td></tr>',
                            ))
                    finally:
                        md._pop(1)
        elif 'expand' in args:
            doc = args['expand']
            if doc in md:
                doc = md.getitem(doc, 0)
            else:
                doc = None
            if doc is not None:
                treeData['-tree-substate-'] = sub
                ptreeData['tree-level'] = level
                md._push(treeData)
                try:
                    output(
                        doc(
                            None,
                            md,
                            standard_html_header=(
                                '<tr>%s<td '
                                'width="16" style="white-space: nowrap"></td>'
                                '<td%s valign="top">' %
                                (h, (dataspan > 1 and
                                     (' colspan="%s"' % dataspan) or ''))),
                            standard_html_footer='</td></tr>',
                        ))
                finally:
                    md._pop(1)
        else:
            __traceback_info__ = sub, args, state, substate
            ids = {}
            for item in items:
                id = extract_id(item, args['id'])
                if len(sub) == 1:
                    sub.append([])
                substate = sub[1]
                ids[id] = 1
                md._push(InstanceDict(item, md))
                try:
                    data = tpRenderTABLE(item, id, root_url, url, state,
                                         substate, diff, data, colspan,
                                         section, md, treeData, level, args)
                finally:
                    md._pop()
                if not sub[1]:
                    del sub[1]

            ids = ids.__contains__
            for i in range(len(substate) - 1, -1):
                if not ids(substate[i][0]):
                    del substate[i]

        if 'footer' in args:
            doc = args['footer']
            if doc in md:
                doc = md.getitem(doc, 0)
            else:
                doc = None
            if doc is not None:
                output(
                    doc(
                        None,
                        md,
                        standard_html_header=(
                            '<tr>%s<td '
                            'width="16" style="white-space: nowrap"></td>'
                            '<td%s valign="top">' %
                            (h, (dataspan > 1 and
                                 (' colspan="%s"' % dataspan) or ''))),
                        standard_html_footer='</td></tr>',
                    ))

    del diff[-1]
    if not diff:
        output('</table>\n')

    return data
def tpRenderTABLE(self, id, root_url, url, state, substate, diff, data,
                  colspan, section, md, treeData, level=0, args=None,
                  try_call_attr=try_call_attr, encoding=None,
                  ):
    "Render a tree as a table"
    encoding = encoding or 'latin-1'
    exp = 0

    if level >= 0:
        urlattr = args['url']
        if urlattr and hasattr(self, urlattr):
            tpUrl = try_call_attr(self, urlattr)
            url = (url and ('%s/%s' % (url, tpUrl))) or tpUrl
            root_url = root_url or tpUrl

    ptreeData = add_with_prefix(treeData, 'tree', args.get('prefix'))
    ptreeData['tree-item-url'] = url
    ptreeData['tree-level'] = level
    ptreeData['tree-item-expanded'] = 0

    output = data.append

    items = None
    if ('assume_children' in args and args['assume_children'] and
            substate is not state):
        # We should not compute children unless we have to.
        # See if we've been asked to expand our children.
        for i in range(len(substate)):
            sub = substate[i]
            if sub[0] == id:
                exp = i + 1
                break
        if not exp:
            items = 1

    get = md.guarded_getattr
    if get is None:
        get = getattr

    if items is None:
        if 'branches' in args and hasattr(self, args['branches']):
            items = get(self, args['branches'])
            items = items()
        elif 'branches_expr' in args:
            items = args['branches_expr'](md)

        if not items and 'leaves' in args:
            items = 1

    if items and items != 1:

        getitem = getattr(md, 'guarded_getitem', None)
        if getitem is not None:
            unauth = []
            for index in range(len(items)):
                try:
                    getitem(items, index)
                except ValidationError:
                    unauth.append(index)
            if unauth:
                if 'skip_unauthorized' in args and args['skip_unauthorized']:
                    items = list(items)
                    unauth.reverse()
                    for index in unauth:
                        del items[index]
                else:
                    raise ValidationError(unauth)

        if 'sort' in args:
            # Faster/less mem in-place sort
            if isinstance(items, tuple):
                items = list(items)
            sort = args['sort']
            size = range(len(items))
            for i in size:
                v = items[i]
                k = getattr(v, sort)
                try:
                    k = k()
                except Exception:
                    pass
                items[i] = (k, v)
            items.sort()
            for i in size:
                items[i] = items[i][1]

        if 'reverse' in args:
            items = list(items)  # Copy the list
            items.reverse()

    if isinstance(id, six.binary_type):
        diff.append(id.decode(encoding))
    else:
        diff.append(id)

    _td_colspan = '<td colspan="%s" style="white-space: nowrap"></td>'
    _td_single = '<td width="16" style="white-space: nowrap"></td>'

    sub = None
    if substate is state:
        output('<table cellspacing="0">\n')
        sub = substate[0]
        exp = items
    else:
        # Add prefix
        output('<tr>\n')

        # Add +/- icon
        if items:
            if level:
                if level > 3:
                    output(_td_colspan % (level - 1))
                elif level > 1:
                    output(_td_single * (level - 1))
                output(_td_single)
                output('\n')
            output('<td width="16" valign="top" style="white-space: nowrap">')
            for i in range(len(substate)):
                sub = substate[i]
                if sub[0] == id:
                    exp = i + 1
                    break

            s = encode_str(compress(json.dumps(diff)))  # bytes in ASCII enc.

            # For rendering the encoded state string in a URL under Python 3,
            # we must lose the "b" prefix by decoding
            if six.PY3:
                s = s.decode('ASCII')

            # Propagate extra args through tree.
            if 'urlparam' in args:
                param = args['urlparam']
                param = "%s&" % param
            else:
                param = ""

            if exp:
                ptreeData['tree-item-expanded'] = 1
                icon = ('<i title="Collapse..."'
                        ' class="fas fa-caret-down text-muted"></i>')
                output('<a name="%s" href="%s?%stree-c=%s#%s">%s</a>' %
                       (id, root_url, param, s, id, icon))
            else:
                icon = ('<i title="Expand..."'
                        ' class="fas fa-caret-right text-muted"></i>')
                output('<a name="%s" href="%s?%stree-e=%s#%s">%s</a>' %
                       (id, root_url, param, s, id, icon))
            output('</td>\n')

        else:
            if level > 2:
                output(_td_colspan % level)
            elif level > 0:
                output(_td_single * level)
            output(_td_single)
            output('\n')

        # add item text
        dataspan = colspan - level
        output('<td%s%s valign="top" align="left">' %
               ((dataspan > 1 and (' colspan="%s"' % dataspan) or ''),
                ('nowrap' in args and
                 args['nowrap'] and ' style="white-space: nowrap"' or ''))
               )
        output(render_blocks(section, md, encoding=encoding))
        output('</td>\n</tr>\n')

    if exp:
        level = level + 1
        dataspan = colspan - level
        if level > 2:
            h = _td_colspan % level
        elif level > 0:
            h = _td_single * level
        else:
            h = ''

        if 'header' in args:
            doc = args['header']
            if doc in md:
                doc = md.getitem(doc, 0)
            else:
                doc = None
            if doc is not None:
                output(doc(
                    None, md,
                    standard_html_header=(
                        '<tr>%s'
                        '<td width="16" style="white-space: nowrap"></td>'
                        '<td%s valign="top">'
                        % (h,
                           (dataspan > 1 and (' colspan="%s"' % dataspan) or
                            ''))),
                    standard_html_footer='</td></tr>',
                ))

        if items == 1:
            # leaves
            if 'leaves' in args:
                doc = args['leaves']
                if doc in md:
                    doc = md.getitem(doc, 0)
                else:
                    doc = None
                if doc is not None:
                    treeData['-tree-substate-'] = sub
                    ptreeData['tree-level'] = level
                    md._push(treeData)
                    try:
                        output(doc(
                            None, md,
                            standard_html_header=(
                                '<tr>%s<td '
                                'width="16" style="white-space: nowrap"></td>'
                                '<td%s valign="top">'
                                % (h,
                                   (dataspan > 1 and
                                    (' colspan="%s"' % dataspan) or ''))),
                            standard_html_footer='</td></tr>',
                        ))
                    finally:
                        md._pop(1)
        elif 'expand' in args:
            doc = args['expand']
            if doc in md:
                doc = md.getitem(doc, 0)
            else:
                doc = None
            if doc is not None:
                treeData['-tree-substate-'] = sub
                ptreeData['tree-level'] = level
                md._push(treeData)
                try:
                    output(doc(
                        None, md,
                        standard_html_header=(
                            '<tr>%s<td '
                            'width="16" style="white-space: nowrap"></td>'
                            '<td%s valign="top">'
                            % (h,
                               (dataspan > 1 and
                                (' colspan="%s"' % dataspan) or ''))),
                        standard_html_footer='</td></tr>',
                    ))
                finally:
                    md._pop(1)
        else:
            __traceback_info__ = sub, args, state, substate
            ids = {}
            for item in items:
                id = extract_id(item, args['id'])
                if len(sub) == 1:
                    sub.append([])
                substate = sub[1]
                ids[id] = 1
                md._push(InstanceDict(item, md))
                try:
                    data = tpRenderTABLE(
                        item, id, root_url, url, state, substate, diff, data,
                        colspan, section, md, treeData, level, args)
                finally:
                    md._pop()
                if not sub[1]:
                    del sub[1]

            ids = ids.__contains__
            for i in range(len(substate) - 1, -1):
                if not ids(substate[i][0]):
                    del substate[i]

        if 'footer' in args:
            doc = args['footer']
            if doc in md:
                doc = md.getitem(doc, 0)
            else:
                doc = None
            if doc is not None:
                output(doc(
                    None, md,
                    standard_html_header=(
                        '<tr>%s<td '
                        'width="16" style="white-space: nowrap"></td>'
                        '<td%s valign="top">'
                        % (h,
                           (dataspan > 1 and (' colspan="%s"' % dataspan) or
                            ''))),
                    standard_html_footer='</td></tr>',
                ))

    del diff[-1]
    if not diff:
        output('</table>\n')

    return data
Beispiel #6
0
def tpRenderTABLE(self, id, root_url, url, state, substate, diff, data,
                  colspan, section, md, treeData, level=0, args=None,
                  try_call_attr=try_call_attr,
                  ):
    "Render a tree as a table"

    have_arg=args.has_key
    exp=0

    if level >= 0:
        urlattr=args['url']
        if urlattr and hasattr(self, urlattr):
            tpUrl = try_call_attr(self, urlattr)
            url = (url and ('%s/%s' % (url, tpUrl))) or tpUrl
            root_url = root_url or tpUrl

    ptreeData = add_with_prefix(treeData, 'tree', args.get('prefix'))
    ptreeData['tree-item-url']=url
    ptreeData['tree-level']=level
    ptreeData['tree-item-expanded']=0
    idattr=args['id']

    output=data.append

    items=None
    if (have_arg('assume_children') and args['assume_children']
        and substate is not state):
        # We should not compute children unless we have to.
        # See if we've been asked to expand our children.
        for i in range(len(substate)):
            sub=substate[i]
            if sub[0]==id:
                exp=i+1
                break
        if not exp: items=1

    get=md.guarded_getattr
    if get is None:
        get = getattr

    if items is None:
        if have_arg('branches') and hasattr(self, args['branches']):
            items = get(self, args['branches'])
            items = items()
        elif have_arg('branches_expr'):
            items=args['branches_expr'](md)

        if not items and have_arg('leaves'): items=1

    if items and items != 1:

        getitem = getattr(md, 'guarded_getitem', None)
        if getitem is not None:
            unauth=[]
            for index in range(len(items)):
                try:
                    getitem(items, index)
                except ValidationError:
                    unauth.append(index)
            if unauth:
                if have_arg('skip_unauthorized') and args['skip_unauthorized']:
                    items=list(items)
                    unauth.reverse()
                    for index in unauth: del items[index]
                else:
                    raise ValidationError, unauth

        if have_arg('sort'):
            # Faster/less mem in-place sort
            if type(items)==type(()):
                items=list(items)
            sort=args['sort']
            size=range(len(items))
            for i in size:
                v=items[i]
                k=getattr(v,sort)
                try:    k=k()
                except: pass
                items[i]=(k,v)
            items.sort()
            for i in size:
                items[i]=items[i][1]

        if have_arg('reverse'):
            items=list(items)           # Copy the list
            items.reverse()

    diff.append(id)


    _td_colspan='<td colspan="%s" style="white-space: nowrap"></td>'
    _td_single ='<td width="16" style="white-space: nowrap"></td>'

    sub=None
    if substate is state:
        output('<table cellspacing="0">\n')
        sub=substate[0]
        exp=items
    else:
        # Add prefix
        output('<tr>\n')

        # Add +/- icon
        if items:
            if level:
                if level > 3:   output(_td_colspan % (level-1))
                elif level > 1: output(_td_single * (level-1))
                output(_td_single)
                output('\n')
            output('<td width="16" valign="top" style="white-space: nowrap">')
            for i in range(len(substate)):
                sub=substate[i]
                if sub[0]==id:
                    exp=i+1
                    break

            ####################################
            # Mostly inline encode_seq for speed
            s=compress(dumps(diff,1))
            if len(s) > 57: s=encode_str(s)
            else:
                s=b2a_base64(s)[:-1]
                l=s.find('=')
                if l >= 0: s=s[:l]
            s=translate(s, tplus)
            ####################################

            script=md['BASEPATH1']

            # Propagate extra args through tree.
            if args.has_key( 'urlparam' ):
                param = args['urlparam']
                param = "%s&" % param
            else:
                param = ""

            if exp:
                ptreeData['tree-item-expanded']=1
                output('<a name="%s" href="%s?%stree-c=%s#%s">'
                       '<img src="%s/p_/mi" alt="-" border="0" /></a>' %
                       (id, root_url, param, s, id, script))
            else:
                output('<a name="%s" href="%s?%stree-e=%s#%s">'
                       '<img src="%s/p_/pl" alt="+" border="0" /></a>' %
                       (id, root_url, param, s, id, script))
            output('</td>\n')

        else:
            if level > 2:   output(_td_colspan % level)
            elif level > 0: output(_td_single  * level)
            output(_td_single)
            output('\n')


        # add item text
        dataspan=colspan-level
        output('<td%s%s valign="top" align="left">' %
               ((dataspan > 1 and (' colspan="%s"' % dataspan) or ''),
               (have_arg('nowrap') and
                args['nowrap'] and ' style="white-space: nowrap"' or ''))
               )
        output(render_blocks(section, md))
        output('</td>\n</tr>\n')


    if exp:

        level=level+1
        dataspan=colspan-level
        if level > 2:   h=_td_colspan % level
        elif level > 0: h=_td_single  * level
        else: h=''

        if have_arg('header'):
            doc=args['header']
            if md.has_key(doc): doc=md.getitem(doc,0)
            else: doc=None
            if doc is not None:
                output(doc(
                    None, md,
                    standard_html_header=(
                        '<tr>%s'
                        '<td width="16" style="white-space: nowrap"></td>'
                        '<td%s valign="top">'
                        % (h,
                           (dataspan > 1 and (' colspan="%s"' % dataspan)
                            or ''))),
                    standard_html_footer='</td></tr>',
                    ))

        if items==1:
            # leaves
            if have_arg('leaves'):
                doc=args['leaves']
                if md.has_key(doc): doc=md.getitem(doc,0)
                else: doc=None
                if doc is not None:
                    treeData['-tree-substate-']=sub
                    ptreeData['tree-level']=level
                    md._push(treeData)
                    try: output(doc(
                        None,md,
                        standard_html_header=(
                            '<tr>%s'
                            '<td width="16" style="white-space: nowrap"></td>'
                            '<td%s valign="top">'
                            % (h,
                               (dataspan > 1 and
                                (' colspan="%s"' % dataspan) or ''))),
                        standard_html_footer='</td></tr>',
                        ))
                    finally: md._pop(1)
        elif have_arg('expand'):
            doc=args['expand']
            if md.has_key(doc): doc=md.getitem(doc,0)
            else: doc=None
            if doc is not None:
                treeData['-tree-substate-']=sub
                ptreeData['tree-level']=level
                md._push(treeData)
                try: output(doc(
                    None,md,
                    standard_html_header=(
                        '<tr>%s<td width="16" style="white-space: nowrap"></td>'
                        '<td%s valign="top">'
                        % (h,
                           (dataspan > 1 and
                            (' colspan="%s"' % dataspan) or ''))),
                    standard_html_footer='</td></tr>',
                    ))
                finally: md._pop(1)
        else:
            __traceback_info__=sub, args, state, substate
            ids={}
            for item in items:
                if hasattr(item, idattr):
                    id = try_call_attr(item, idattr)
                elif hasattr(item, '_p_oid'): id=oid(item)
                else: id=pyid(item)
                if len(sub)==1: sub.append([])
                substate=sub[1]
                ids[id]=1
                md._push(InstanceDict(item,md))
                try: data=tpRenderTABLE(
                    item,id,root_url,url,state,substate,diff,data,
                    colspan, section, md, treeData, level, args)
                finally: md._pop()
                if not sub[1]: del sub[1]

            ids=ids.has_key
            for i in range(len(substate)-1,-1):
                if not ids(substate[i][0]): del substate[i]

        if have_arg('footer'):
            doc=args['footer']
            if md.has_key(doc): doc=md.getitem(doc,0)
            else: doc=None
            if doc is not None:
                output(doc(
                    None, md,
                    standard_html_header=(
                        '<tr>%s<td width="16" style="white-space: nowrap"></td>'
                        '<td%s valign="top">'
                        % (h,
                           (dataspan > 1 and (' colspan="%s"' % dataspan)
                            or ''))),
                    standard_html_footer='</td></tr>',
                    ))

    del diff[-1]
    if not diff: output('</table>\n')

    return data
    def renderwob(self, md):
        """RENDER WithOutBatch"""
        expr=self.expr
        name=self.__name__
        if expr is None:
            sequence=md[name]
            cache={ name: sequence }
        else:
            sequence=expr(md)
            cache=None

        if not sequence:
            if self.elses: return render_blocks(self.elses, md)
            return ''

        if type(sequence) is type(''):
            raise ValueError, (
                'Strings are not allowed as input to the in tag.')

        section=self.section
        mapping=self.mapping
        no_push_item=self.no_push_item

        if self.sort_expr is not None:
            self.sort=self.sort_expr.eval(md)
            sequence=self.sort_sequence(sequence, md)
        elif self.sort is not None:
            sequence=self.sort_sequence(sequence, md)

        if self.reverse_expr is not None and self.reverse_expr.eval(md):
            sequence=self.reverse_sequence(sequence)
        elif self.reverse is not None:
            sequence=self.reverse_sequence(sequence)

        prefix = self.args.get('prefix')
        vars=sequence_variables(sequence, alt_prefix=prefix)
        kw=vars.data
        pkw = add_with_prefix(kw, 'sequence', prefix)
        for k, v in kw.items():
            pkw[k] = v
        kw['mapping']=mapping

        l=len(sequence)
        last=l-1

        push=md._push
        pop=md._pop
        render=render_blocks

        if cache: push(cache)
        push(vars)
        try:
            result = []
            append=result.append
            guarded_getitem = getattr(md, 'guarded_getitem', None)
            for index in range(l):
                if index==last: pkw['sequence-end']=1
                if guarded_getitem is not None:
                    try: client = guarded_getitem(sequence, index)
                    except ValidationError, vv:
                        if (self.args.has_key('skip_unauthorized') and
                            self.args['skip_unauthorized']):
                            if index==1: pkw['sequence-start']=0
                            continue
                        raise ValidationError, '(item %s): %s' % (
                            index, vv), sys.exc_info()[2]
                else:
                    client = sequence[index]

                pkw['sequence-index']=index
                t = type(client)
                if t is TupleType and len(client)==2:
                    client=client[1]

                if no_push_item:
                    pushed = 0
                elif mapping:
                    pushed = 1
                    push(client)
                elif t in StringTypes:
                    pushed = 0
                else:
                    pushed = 1
                    push(InstanceDict(client, md))

                try: append(render(section, md))
                finally:
                    if pushed:
                        pop()
                if index==0: pkw['sequence-start']=0

            result = join_unicode(result)
    def renderwb(self, md):
        expr=self.expr
        name=self.__name__
        if expr is None:
            sequence=md[name]
            cache={ name: sequence }
        else:
            sequence=expr(md)
            cache=None

        if not sequence:
            if self.elses: return render_blocks(self.elses, md)
            return ''

        if type(sequence) is type(''):
            raise ValueError, (
                'Strings are not allowed as input to the in tag.')


        section=self.section
        params=self.args

        mapping=self.mapping
        no_push_item=self.no_push_item

        if self.sort_expr is not None:
            self.sort=self.sort_expr.eval(md)
            sequence=self.sort_sequence(sequence, md)
        elif self.sort is not None:
            sequence=self.sort_sequence(sequence, md)

        if self.reverse_expr is not None and self.reverse_expr.eval(md):
            sequence=self.reverse_sequence(sequence)
        elif self.reverse is not None:
            sequence=self.reverse_sequence(sequence)

        next=previous=0
        try: start=int_param(params,md,'start',0)
        except: start=1
        end=int_param(params,md,'end',0)
        size=int_param(params,md,'size',0)
        overlap=int_param(params,md,'overlap',0)
        orphan=int_param(params,md,'orphan','0')
        start,end,sz=opt(start,end,size,orphan,sequence)
        if params.has_key('next'): next=1
        if params.has_key('previous'): previous=1

        last=end-1
        first=start-1

        try: query_string=md['QUERY_STRING']
        except: query_string=''
        prefix = params.get('prefix')
        vars = sequence_variables(sequence, '?'+query_string,
                                  self.start_name_re, prefix)
        kw=vars.data
        pkw = add_with_prefix(kw, 'sequence', prefix)
        for k, v in kw.items():
            pkw[k] = v
        pkw['sequence-step-size']=sz
        pkw['sequence-step-overlap']=overlap
        pkw['sequence-step-start']=start
        pkw['sequence-step-end']=end
        pkw['sequence-step-start-index']=start-1
        pkw['sequence-step-end-index']=end-1
        pkw['sequence-step-orphan']=orphan

        kw['mapping']=mapping

        push=md._push
        pop=md._pop
        render=render_blocks

        if cache: push(cache)
        push(vars)
        try:
            if previous:
                if first > 0:
                    pstart,pend,psize=opt(0,first+overlap,
                                          sz,orphan,sequence)
                    pkw['previous-sequence']=1
                    pkw['previous-sequence-start-index']=pstart-1
                    pkw['previous-sequence-end-index']=pend-1
                    pkw['previous-sequence-size']=pend+1-pstart
                    result=render(section,md)

                elif self.elses: result=render(self.elses, md)
                else: result=''
            elif next:
                try:
                    # The following line is a sneaky way to test whether
                    # there are more items, without actually
                    # computing a length:
                    sequence[end]
                except IndexError:
                    if self.elses: result=render(self.elses, md)
                    else: result=''
                else:
                    pstart,pend,psize=opt(end+1-overlap,0,
                                          sz,orphan,sequence)
                    pkw['next-sequence']=1
                    pkw['next-sequence-start-index']=pstart-1
                    pkw['next-sequence-end-index']=pend-1
                    pkw['next-sequence-size']=pend+1-pstart
                    result=render(section,md)
            else:
                result = []
                append=result.append
                guarded_getitem = getattr(md, 'guarded_getitem', None)
                for index in range(first,end):
                    # preset
                    pkw['previous-sequence']= 0
                    pkw['next-sequence']= 0 # now more often defined then previously
                    #
                    if index==first or index==last:
                        # provide batching information
                        if first > 0:
                            pstart,pend,psize=opt(0,first+overlap,
                                                  sz,orphan,sequence)
                            if index==first: pkw['previous-sequence']=1
                            pkw['previous-sequence-start-index']=pstart-1
                            pkw['previous-sequence-end-index']=pend-1
                            pkw['previous-sequence-size']=pend+1-pstart
                        try:
                            # The following line is a sneaky way to
                            # test whether there are more items,
                            # without actually computing a length:
                            sequence[end]
                            pstart,pend,psize=opt(end+1-overlap,0,
                                                  sz,orphan,sequence)
                            if index==last: pkw['next-sequence']=1
                            pkw['next-sequence-start-index']=pstart-1
                            pkw['next-sequence-end-index']=pend-1
                            pkw['next-sequence-size']=pend+1-pstart
                        except: pass

                    if index==last: pkw['sequence-end']=1

                    if guarded_getitem is not None:
                        try: client = guarded_getitem(sequence, index)
                        except ValidationError, vv:
                            if (params.has_key('skip_unauthorized') and
                                params['skip_unauthorized']):
                                if index==first: pkw['sequence-start']=0
                                continue
                            raise ValidationError, '(item %s): %s' % (
                                index, vv), sys.exc_info()[2]
                    else:
                        client = sequence[index]

                    pkw['sequence-index']=index
                    t = type(client)
                    if t is TupleType and len(client)==2:
                        client=client[1]

                    if no_push_item:
                        pushed = 0
                    elif mapping:
                        pushed = 1
                        push(client)
                    elif t in StringTypes:
                        pushed = 0
                    else:
                        pushed = 1
                        push(InstanceDict(client, md))

                    try: append(render(section, md))
                    finally:
                        if pushed:
                            pop()

                    if index==first: pkw['sequence-start']=0


                result = join_unicode(result)

        finally:
            if cache: pop()
            pop()

        return result