summaryrefslogtreecommitdiff
path: root/validation/validlib/rst_utils.py
blob: 5858be6a39f1ce7dd104c6470100ea3098dadce1 (plain)
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
# -*- coding: utf-8 -*-

import subprocess
import re
import os
import gzip

import list_utils

def rst2pdf(file_name):
    input_file_name = file_name + ".rst"
    output_file_name = file_name + ".pdf"
    subprocess.check_call(["rst2pdf", input_file_name, "-o", output_file_name])
    print output_file_name, "has been generated"

def title_break(character):
    return "\n" + 80 * character + "\n\n"

def page_break():
    return "" \
        ".. raw:: pdf\n" \
        "\n" \
        "   PageBreak\n" \
        "\n"

def traces(files_paths, root):
    """ Extract the text contained in zip files and display them in a
    synthetic way"""
    files_paths = list_utils.flatten(files_paths)
    if files_paths == []:
        return ""
    heads_and_tails = get_heads_and_tails(root, files_paths)
    formatted_head_and_tails =  map(lambda x: format_head_and_tails(root, x),
                                    heads_and_tails)
    return page_break() + \
        "Traces\n" \
        "======\n" + \
        "All traces are available in " + root + ".\n\n" + \
        page_break().join(formatted_head_and_tails)

############### Internal functions ###############

def get_heads_and_tails(root, files_paths):
    """We group here the files paths having the same head, i.e. the same
    beginning of path, excluding the root"""
    heads_and_tails = map(lambda x: get_head_and_tail(x, root),
                          files_paths)
    [heads, tails] = zip(*heads_and_tails)
    distinct_heads = list_utils.drop_duplicates(heads)
    result = []
    for distinct_head in distinct_heads:
        tails_per_distinct_head = []
        for (head, tail) in heads_and_tails:
            if head == distinct_head:
                tails_per_distinct_head.append(tail)
        tails_per_distinct_head.sort()
        result.append((distinct_head, tails_per_distinct_head))
    result.sort()
    return result

def get_head_and_tail(file_path, root):
    pattern = "^" + root + "/(.*)"
    file_path = re.search(pattern, file_path).groups()[0]
    file_path = file_path.split("/")
    length = len(file_path)
    head = "/".join(file_path[0:length - 3])
    tail = "/".join(file_path[length - 3:length])
    return (head, tail)

def format_head_and_tails(root, (head, tails)):

    formated_tails_groups = []
    # We must group by 8 because we cannot put more than 8 traces on an A4 page
    for tails_group in group_by(5, tails):
        formated_tails_group = "".join(map(lambda x: format_tail(root, head, x),
                                          tails_group))
        formated_tails_groups.append(formated_tails_group)

    return "- " + head.replace(" ", "\\\ ") + "\n\n" + \
        page_break().join(formated_tails_groups) + \
        "\n"

def group_by(group_size, elements):
    """Group elements by groups of group_size"""
    return group_by_aux(group_size, elements, [])

def group_by_aux(group_size, elements, acc):
    if elements == []:
        return acc
    if len(elements) < group_size:
        acc.append(elements)
        return acc
    acc.append(elements[0:group_size])
    return group_by_aux(group_size, elements[group_size:len(elements)], acc)

def format_tail(root, head, tail):
    path = os.path.join(root, head, tail)
    content = unzip(path)
    content = content.split("\n")
    content = content[0:5]
    content = map(shred, content)
    content =  "".join(content)
    return tail.replace(" ", "\\\ ") + "\n\n:: \n\n" + content + "\n\n"

def shred(line):
    """Shred a line in several lines of 80 characters at most"""
    sublines = group_by(80, line)
    return "".join([ "  " + subline + "\n" for subline in sublines ])

def unzip(zip_file_path):
    zip_file_handler = gzip.open(zip_file_path, 'rb')
    zip_file_content = zip_file_handler.read()
    zip_file_handler.close()
    return zip_file_content

if __name__ == "__main__":

    assert ("head1/head2", "tail1/tail2/tail3") == \
        get_head_and_tail("root1/root2/head1/head2/tail1/tail2/tail3",
                          "root1/root2")

    assert [("head1/head2", ["tail1/tail2/tail3"])] == \
        get_heads_and_tails("root1/root2",
                            ["root1/root2/head1/head2/tail1/tail2/tail3"])

    assert [("head1/head2", ["tail1/tail2/tail3", "tail1/tail2/tail3"])] == \
        get_heads_and_tails("root1/root2",
                            ["root1/root2/head1/head2/tail1/tail2/tail3",
                             "root1/root2/head1/head2/tail1/tail2/tail3"])

    assert [("head1/head2", ["tail1/tail2/tail3", "tail1/tail2/tail3"]),
            ("head3", ["tail1/tail2/tail3"])] == \
            get_heads_and_tails("root1/root2",
                                ["root1/root2/head1/head2/tail1/tail2/tail3",
                                 "root1/root2/head1/head2/tail1/tail2/tail3",
               "root1/root2/head3/tail1/tail2/tail3"])

    assert [] == group_by(8, [])
    assert [[1]] == group_by(8, [1])
    assert [[1, 2]] == group_by(8, [1, 2])
    assert [[1, 2, 3, 4, 5, 6, 7, 8]] == \
        group_by(8, [1, 2, 3, 4, 5, 6, 7, 8])
    assert [[1, 2, 3, 4, 5, 6, 7, 8], [9]] == \
        group_by(8, [1, 2, 3, 4, 5, 6, 7, 8, 9])