Пример #1
0
def _render_multirow(events, time_map, max_height):
    """Render a complex format that contains a multi-row R3 event.
    """
    sp_event, *events = events
    # Sort events by time, and then location. This is done here because
    # we need to exclude the R3 event (by putting it first).
    events = sorted(events, key=lambda e: (e.begin_time.value, e.location))
    event_iter = iter(events)

    # Render R0-R2 events in the first time period.
    cells = _render_multirow_subrow(event_iter, time_map, events)

    # Render the multi-row R3 event.
    cells.extend([
        render_attached_period(sp_event.begin_time, sp_event.end_time),
        render_block(
            sp_event, time_map, events, ['pull-right'],
            max_height=max_height,
        ),
    ])

    # Render the rest of the events.
    try:
        while True:
            cells += _render_multirow_subrow(event_iter, time_map, events)
    except StopIteration:
        pass

    # Join the results.
    return html_join('', cells)
Пример #2
0
def render_table(day):
    events = itertools.chain.from_iterable(
        _filter_events(Cls, day)
        for Cls in EVENT_CLASSES
    )
    groups = collect_event_groups(events)

    head = mark_safe("""
        <div class="time-table__header">
          <div class="time-table__time"></div>
          <div class="time-table__slot">
            <div class="row">
              <div class="slot-item header-cell header-cell--r0">R0</div>
              <div class="slot-item header-cell header-cell--r1">R1</div>
              <div class="slot-item header-cell header-cell--r2">R2</div>
              <div class="slot-item header-cell header-cell--r3">R3</div>
            </div>
          </div>
        </div>
    """)
    body = html_join('', (
        render_row(times, group) for times, group in groups.items()
    ))
    return format_html(
        '<div class="time-table clearfix">{head}{body}</div>',
        head=head, body=body,
    )
Пример #3
0
def _render_multirow(events, time_map, max_height):
    """Render a complex format that contains a multi-row R3 event.
    """
    sp_event, *events = events
    # Sort events by time, and then location. This is done here because
    # we need to exclude the R3 event (by putting it first).
    events = sorted(events, key=lambda e: (e.begin_time.value, e.location))
    event_iter = iter(events)

    # Render R0-R2 events in the first time period.
    cells = _render_multirow_subrow(event_iter, time_map, events)

    # Render the multi-row R3 event.
    cells.extend([
        render_attached_period(sp_event.begin_time, sp_event.end_time),
        render_block(
            sp_event, time_map, events, ['pull-right'],
            max_height=max_height,
        ),
    ])

    # Render the rest of the events.
    try:
        while True:
            cells += _render_multirow_subrow(event_iter, time_map, events)
    except StopIteration:
        pass

    # Join the results.
    return html_join('', cells)
Пример #4
0
def block_diff(current, snapshot):
    return html_join(
        mark_safe('<br>'),
        difftools.make_diff(
            snapshot.splitlines(),
            current.splitlines(),
        ))
Пример #5
0
def render_table(day):
    events = itertools.chain.from_iterable(
        _filter_events(Cls, day)
        for Cls in EVENT_CLASSES
    )
    groups = collect_event_groups(events)

    head = mark_safe("""
        <div class="time-table__header">
          <div class="time-table__time"></div>
          <div class="time-table__slot">
            <div class="row">
              <div class="slot-item header-cell header-cell--r0">R0</div>
              <div class="slot-item header-cell header-cell--r1">R1</div>
              <div class="slot-item header-cell header-cell--r2">R2</div>
              <div class="slot-item header-cell header-cell--r3">R3</div>
            </div>
          </div>
        </div>
    """)
    body = html_join('', (
        render_row(times, group) for times, group in groups.items()
    ))
    return format_html(
        '<div class="time-table clearfix">{head}{body}</div>',
        head=head, body=body,
    )
Пример #6
0
def _render_blocks(events, time_map):
    """Render a R0-3 belt, a R0-2 partial belt (plus optionally a R3 event),
    or an all-block (with or without R3) format.
    """
    if events[0].location == Location.R3:
        # If this contains R3, shuffle it to the back.
        r3_event, *events = events

        # If this is not a smooth row, we need to prevent any block from
        # being rendered as short because we can't handle it with multi-height.
        if any(r3_event.end_time != e.end_time for e in events):
            min_height = 1
        else:
            min_height = 0
        r3_block = render_block(
            r3_event,
            time_map,
            events,
            min_height=min_height,
        )
    else:
        r3_event = None
        r3_block = ''

    # Render period block for R3.
    # We cheat a little here: Times in R0-2 are supposed to be identical;
    # only R3 can be different. We just compare the first event's times
    # and R3's. If they are identical, R3 does not need its own period block,
    # otherwise it does.
    r3_period = ''
    rx_begin, rx_end = events[0].begin_time, events[0].end_time
    if r3_event:
        r3_begin = r3_event.begin_time
        r3_end = r3_event.end_time
        if r3_begin != rx_begin or r3_end != rx_end:
            r3_period = render_attached_period(r3_begin, r3_end)

    return format_html(
        '{r012_period}{r012_blocks}{r3_period}{r3_block}',
        r012_period=render_attached_period(rx_begin, rx_end),
        r012_blocks=html_join(
            '',
            (render_block(e, time_map, events) for e in events),
        ),
        r3_period=r3_period,
        r3_block=r3_block,
    )
Пример #7
0
def _render_blocks(events, time_map):
    """Render a R0-3 belt, a R0-2 partial belt (plus optionally a R3 event),
    or an all-block (with or without R3) format.
    """
    if events[0].location == Location.R3:
        # If this contains R3, shuffle it to the back.
        r3_event, *events = events

        # If this is not a smooth row, we need to prevent any block from
        # being rendered as short because we can't handle it with multi-height.
        if any(r3_event.end_time != e.end_time for e in events):
            min_height = 1
        else:
            min_height = 0
        r3_block = render_block(
            r3_event, time_map, events, min_height=min_height,
        )
    else:
        r3_event = None
        r3_block = ''

    # Render period block for R3.
    # We cheat a little here: Times in R0-2 are supposed to be identical;
    # only R3 can be different. We just compare the first event's times
    # and R3's. If they are identical, R3 does not need its own period block,
    # otherwise it does.
    r3_period = ''
    rx_begin, rx_end = events[0].begin_time, events[0].end_time
    if r3_event:
        r3_begin = r3_event.begin_time
        r3_end = r3_event.end_time
        if r3_begin != rx_begin or r3_end != rx_end:
            r3_period = render_attached_period(r3_begin, r3_end)

    return format_html(
        '{r012_period}{r012_blocks}{r3_period}{r3_block}',
        r012_period=render_attached_period(rx_begin, rx_end),
        r012_blocks=html_join(
            '',
            (render_block(e, time_map, events) for e in events),
        ),
        r3_period=r3_period,
        r3_block=r3_block,
    )
Пример #8
0
def render_all():
    return html_join('', (
        render_day(day, display)
        for day, display in settings.EVENTS_DAY_NAMES.items()
    ))
Пример #9
0
def render_all():
    return html_join('', (
        render_day(day, display)
        for day, display in settings.EVENTS_DAY_NAMES.items()
    ))
Пример #10
0
def dump_replace(a, b, alo, blo, ahi, bhi):  # noqa
    # Based on `difflib.Differ._fancy_replace`.
    # When replacing one block of lines with another, search the blocks
    # for *similar* lines; the best-matching pair (if any) is used as a
    # sync point, and intraline difference marking is done on the
    # similar pair. Lots of work, but often worth it.
    best_ratio = 0
    cutoff = 0.8
    cruncher = difflib.SequenceMatcher(difflib.IS_CHARACTER_JUNK)
    eqi, eqj = None, None

    # Search for the first sync point.
    for j in range(blo, bhi):
        bj = b[j]
        cruncher.set_seq2(bj)
        for i in range(alo, ahi):
            ai = a[i]
            if ai == bj:
                if eqi is None:
                    eqi, eqj = i, j
                continue
            cruncher.set_seq1(ai)
            if (cruncher.real_quick_ratio() > best_ratio
                    and cruncher.quick_ratio() > best_ratio
                    and cruncher.ratio() > best_ratio):
                best_ratio, best_i, best_j = cruncher.ratio(), i, j

    # No "pretty close" pair.
    if best_ratio < cutoff:
        if eqi is None:  # No identical pairs. Just dump.
            yield from dump_delete(a, b, alo, blo, ahi, bhi)
            yield from dump_insert(a, b, alo, blo, ahi, bhi)
            return
        # There's an identical pair. Use that.
        best_i, best_j, best_ratio = eqi, eqj, 1.0
    else:
        eqi = None

    # Dump things before the sync point.
    yield from replace_helper(a, alo, best_i, b, blo, best_j)

    # Intraline marking.
    aelt, belt = a[best_i], b[best_j]
    if eqi is None:
        atags = []
        btags = []
        cruncher.set_seqs(aelt, belt)
        for tag, ai1, ai2, bj1, bj2 in cruncher.get_opcodes():
            acon, bcon = aelt[ai1:ai2], belt[bj1:bj2]
            if tag == 'replace':
                atags.append(format_html('<del>{}</del>', acon))
                btags.append(format_html('<ins>{}</ins>', bcon))
            elif tag == 'delete':
                atags.append(format_html('<del>{}</del>', acon))
            elif tag == 'insert':
                btags.append(format_html('<ins>{}</ins>', bcon))
            else:  # Equal.
                atags.append(acon)
                btags.append(bcon)
        yield format_html('<del>{}</del>', html_join('', atags))
        yield format_html('<ins>{}</ins>', html_join('', btags))
    else:  # Identical.
        yield aelt

    # Dump things after the sync point.
    yield from replace_helper(a, best_i + 1, ahi, b, best_j + 1, bhi)
Пример #11
0
def render_all():
    return html_join('', (
        render_day(day, display)
        for day, display in DAY_NAMES.items()
    ))
Пример #12
0
def dump_replace(a, b, alo, blo, ahi, bhi):
    # Based on `difflib.Differ._fancy_replace`.
    # When replacing one block of lines with another, search the blocks
    # for *similar* lines; the best-matching pair (if any) is used as a
    # sync point, and intraline difference marking is done on the
    # similar pair. Lots of work, but often worth it.
    best_ratio = 0
    cutoff = 0.8
    cruncher = difflib.SequenceMatcher(difflib.IS_CHARACTER_JUNK)
    eqi, eqj = None, None

    # Search for the first sync point.
    for j in range(blo, bhi):
        bj = b[j]
        cruncher.set_seq2(bj)
        for i in range(alo, ahi):
            ai = a[i]
            if ai == bj:
                if eqi is None:
                    eqi, eqj = i, j
                continue
            cruncher.set_seq1(ai)
            if (cruncher.real_quick_ratio() > best_ratio and
                    cruncher.quick_ratio() > best_ratio and
                    cruncher.ratio() > best_ratio):
                best_ratio, best_i, best_j = cruncher.ratio(), i, j

    # No "pretty close" pair.
    if best_ratio < cutoff:
        if eqi is None:     # No identical pairs. Just dump.
            yield from dump_delete(a, b, alo, blo, ahi, bhi)
            yield from dump_insert(a, b, alo, blo, ahi, bhi)
            return
        # There's an identical pair. Use that.
        best_i, best_j, best_ratio = eqi, eqj, 1.0
    else:
        eqi = None

    # Dump things before the sync point.
    yield from replace_helper(a, alo, best_i, b, blo, best_j)

    # Intraline marking.
    aelt, belt = a[best_i], b[best_j]
    if eqi is None:
        atags = []
        btags = []
        cruncher.set_seqs(aelt, belt)
        for tag, ai1, ai2, bj1, bj2 in cruncher.get_opcodes():
            acon, bcon = aelt[ai1:ai2], belt[bj1:bj2]
            if tag == 'replace':
                atags.append(format_html('<del>{}</del>', acon))
                btags.append(format_html('<ins>{}</ins>', bcon))
            elif tag == 'delete':
                atags.append(format_html('<del>{}</del>', acon))
            elif tag == 'insert':
                btags.append(format_html('<ins>{}</ins>', bcon))
            else:   # Equal.
                atags.append(acon)
                btags.append(bcon)
        yield format_html('<del>{}</del>', html_join('', atags))
        yield format_html('<ins>{}</ins>', html_join('', btags))
    else:   # Identical.
        yield aelt

    # Dump things after the sync point.
    yield from replace_helper(a, best_i + 1, ahi, b, best_j + 1, bhi)