Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
diffoscope
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Reproducible Builds
diffoscope
Commits
2a0314c3
Commit
2a0314c3
authored
Jun 14, 2017
by
Ximin Luo
Browse files
Options
Downloads
Patches
Plain Diff
Refactor html-dir presenter to be a class instance, avoiding global state
No functionality should have been modified by this commit
parent
ad28ed35
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
diffoscope/presenters/html/html.py
+406
-425
406 additions, 425 deletions
diffoscope/presenters/html/html.py
with
406 additions
and
425 deletions
diffoscope/presenters/html/html.py
+
406
−
425
View file @
2a0314c3
...
...
@@ -71,49 +71,6 @@ logger = logging.getLogger(__name__)
re_anchor_prefix
=
re
.
compile
(
r
'
^[^A-Za-z]
'
)
re_anchor_suffix
=
re
.
compile
(
r
'
[^A-Za-z-_:\.]
'
)
buf
,
add_cpt
,
del_cpt
=
[],
0
,
0
line1
,
line2
,
has_internal_linenos
=
0
,
0
,
True
hunk_off1
,
hunk_size1
,
hunk_off2
,
hunk_size2
=
0
,
0
,
0
,
0
spl_rows
,
spl_current_page
=
0
,
0
spl_print_func
,
spl_print_ctrl
=
None
,
None
class
HTMLPresenter
(
Presenter
):
supports_visual_diffs
=
True
@classmethod
def
run
(
cls
,
data
,
difference
,
parsed_args
):
with
make_printer
(
parsed_args
.
html_output
)
as
fn
:
output_html
(
difference
,
css_url
=
parsed_args
.
css_url
,
print_func
=
fn
,
)
class
HTMLDirectoryPresenter
(
HTMLPresenter
):
@classmethod
def
run
(
cls
,
data
,
difference
,
parsed_args
):
output_html_directory
(
parsed_args
.
html_output_directory
,
difference
,
css_url
=
parsed_args
.
css_url
,
jquery_url
=
parsed_args
.
jquery_url
,
)
def
new_unified_diff
():
global
buf
,
add_cpt
,
del_cpt
global
line1
,
line2
,
has_internal_linenos
global
hunk_off1
,
hunk_size1
,
hunk_off2
,
hunk_size2
global
spl_rows
,
spl_current_page
global
spl_print_func
,
spl_print_ctrl
buf
,
add_cpt
,
del_cpt
=
[],
0
,
0
line1
,
line2
,
has_internal_linenos
=
0
,
0
,
True
hunk_off1
,
hunk_size1
,
hunk_off2
,
hunk_size2
=
0
,
0
,
0
,
0
spl_rows
,
spl_current_page
=
0
,
0
spl_print_func
,
spl_print_ctrl
=
None
,
None
def
convert
(
s
,
ponct
=
0
,
tag
=
''
):
i
=
0
...
...
@@ -152,16 +109,97 @@ def convert(s, ponct=0, tag=''):
return
t
.
getvalue
()
def
output_visual
(
print_func
,
visual
,
parents
):
logger
.
debug
(
'
including image for %s
'
,
visual
.
source
)
sources
=
parents
+
[
visual
.
source
]
print_func
(
u
'
<div class=
"
difference
"
>
'
)
print_func
(
u
'
<div class=
"
diffheader
"
>
'
)
print_func
(
u
'
<div class=
"
diffcontrol
"
>⊟</div>
'
)
print_func
(
u
'
<div><span class=
"
source
"
>%s</span>
'
%
html
.
escape
(
visual
.
source
))
anchor
=
escape_anchor
(
'
/
'
.
join
(
sources
[
1
:]))
print_func
(
u
'
<a class=
"
anchor
"
href=
"
#%s
"
name=
"
%s
"
>
\xb6
</a>
'
%
(
anchor
,
anchor
))
print_func
(
u
"
</div>
"
)
print_func
(
u
"
</div>
"
)
print_func
(
u
'
<div class=
"
difference
"
>
'
u
'
<img src=
\"
data:%s,%s
\"
alt=
\"
compared images
\"
/></div>
'
%
(
visual
.
data_type
,
visual
.
content
))
print_func
(
u
"
</div>
"
,
force
=
True
)
def
escape_anchor
(
val
):
"""
ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed
by any number of letters, digits ([0-9]), hyphens (
"
-
"
), underscores (
"
_
"
),
colons (
"
:
"
), and periods (
"
.
"
).
"""
for
pattern
,
repl
in
(
(
re_anchor_prefix
,
'
D
'
),
(
re_anchor_suffix
,
'
-
'
),
):
val
=
pattern
.
sub
(
repl
,
val
)
return
val
def
output_header
(
css_url
,
print_func
):
if
css_url
:
css_link
=
'
<link href=
"
%s
"
type=
"
text/css
"
rel=
"
stylesheet
"
/>
'
%
css_url
else
:
css_link
=
''
print_func
(
templates
.
HEADER
%
{
'
title
'
:
html
.
escape
(
'
'
.
join
(
sys
.
argv
)),
'
favicon
'
:
FAVICON_BASE64
,
'
css_link
'
:
css_link
,
})
def
output_footer
(
print_func
):
print_func
(
templates
.
FOOTER
%
{
'
version
'
:
VERSION
},
force
=
True
)
def
output_hunk
():
spl_print_func
(
u
'
<tr class=
"
diffhunk
"
><td colspan=
"
2
"
>Offset %d, %d lines modified</td>
'
%
(
hunk_off1
,
hunk_size1
))
spl_print_func
(
u
'
<td colspan=
"
2
"
>Offset %d, %d lines modified</td></tr>
\n
'
%
(
hunk_off2
,
hunk_size2
))
row_was_output
()
@contextlib.contextmanager
def
file_printer
(
directory
,
filename
):
with
codecs
.
open
(
os
.
path
.
join
(
directory
,
filename
),
'
w
'
,
encoding
=
'
utf-8
'
)
as
f
:
yield
f
.
write
@contextlib.contextmanager
def
spl_file_printer
(
directory
,
filename
):
with
codecs
.
open
(
os
.
path
.
join
(
directory
,
filename
),
'
w
'
,
encoding
=
'
utf-8
'
)
as
f
:
print_func
=
f
.
write
def
recording_print_func
(
s
,
force
=
False
):
print_func
(
s
)
recording_print_func
.
bytes_written
+=
len
(
s
)
recording_print_func
.
bytes_written
=
0
yield
recording_print_func
def
output_line
(
s1
,
s2
):
global
line1
,
line2
,
has_internal_linenos
class
HTMLPresenter
(
Presenter
):
supports_visual_diffs
=
True
def
__init__
(
self
):
self
.
new_unified_diff
()
def
new_unified_diff
(
self
):
self
.
buf
=
[]
self
.
add_cpt
=
0
self
.
del_cpt
=
0
self
.
line1
=
0
self
.
line2
=
0
self
.
has_internal_linenos
=
True
self
.
hunk_off1
=
0
self
.
hunk_size1
=
0
self
.
hunk_off2
=
0
self
.
hunk_size2
=
0
self
.
spl_rows
=
0
self
.
spl_current_page
=
0
self
.
spl_print_func
=
None
self
.
spl_print_ctrl
=
None
def
output_hunk
(
self
):
self
.
spl_print_func
(
u
'
<tr class=
"
diffhunk
"
><td colspan=
"
2
"
>Offset %d, %d lines modified</td>
'
%
(
self
.
hunk_off1
,
self
.
hunk_size1
))
self
.
spl_print_func
(
u
'
<td colspan=
"
2
"
>Offset %d, %d lines modified</td></tr>
\n
'
%
(
self
.
hunk_off2
,
self
.
hunk_size2
))
self
.
row_was_output
()
def
output_line
(
self
,
s1
,
s2
):
orig1
=
s1
orig2
=
s2
...
...
@@ -184,57 +222,52 @@ def output_line(s1, s2):
type_name
=
"
changed
"
s1
,
s2
=
linediff
(
s1
,
s2
,
DIFFON
,
DIFFOFF
)
spl_print_func
(
u
'
<tr class=
"
diff%s
"
>
'
%
type_name
)
self
.
spl_print_func
(
u
'
<tr class=
"
diff%s
"
>
'
%
type_name
)
try
:
if
s1
:
if
has_internal_linenos
:
spl_print_func
(
u
'
<td colspan=
"
2
"
class=
"
diffpresent
"
>
'
)
if
self
.
has_internal_linenos
:
self
.
spl_print_func
(
u
'
<td colspan=
"
2
"
class=
"
diffpresent
"
>
'
)
else
:
spl_print_func
(
u
'
<td class=
"
diffline
"
>%d </td>
'
%
line1
)
spl_print_func
(
u
'
<td class=
"
diffpresent
"
>
'
)
spl_print_func
(
convert
(
s1
,
ponct
=
1
,
tag
=
'
del
'
))
spl_print_func
(
u
'
</td>
'
)
self
.
spl_print_func
(
u
'
<td class=
"
diffline
"
>%d </td>
'
%
self
.
line1
)
self
.
spl_print_func
(
u
'
<td class=
"
diffpresent
"
>
'
)
self
.
spl_print_func
(
convert
(
s1
,
ponct
=
1
,
tag
=
'
del
'
))
self
.
spl_print_func
(
u
'
</td>
'
)
else
:
spl_print_func
(
u
'
<td colspan=
"
2
"
>
\xa0
</td>
'
)
self
.
spl_print_func
(
u
'
<td colspan=
"
2
"
>
\xa0
</td>
'
)
if
s2
:
if
has_internal_linenos
:
spl_print_func
(
u
'
<td colspan=
"
2
"
class=
"
diffpresent
"
>
'
)
if
self
.
has_internal_linenos
:
self
.
spl_print_func
(
u
'
<td colspan=
"
2
"
class=
"
diffpresent
"
>
'
)
else
:
spl_print_func
(
u
'
<td class=
"
diffline
"
>%d </td>
'
%
line2
)
spl_print_func
(
u
'
<td class=
"
diffpresent
"
>
'
)
spl_print_func
(
convert
(
s2
,
ponct
=
1
,
tag
=
'
ins
'
))
spl_print_func
(
u
'
</td>
'
)
self
.
spl_print_func
(
u
'
<td class=
"
diffline
"
>%d </td>
'
%
self
.
line2
)
self
.
spl_print_func
(
u
'
<td class=
"
diffpresent
"
>
'
)
self
.
spl_print_func
(
convert
(
s2
,
ponct
=
1
,
tag
=
'
ins
'
))
self
.
spl_print_func
(
u
'
</td>
'
)
else
:
spl_print_func
(
u
'
<td colspan=
"
2
"
>
\xa0
</td>
'
)
self
.
spl_print_func
(
u
'
<td colspan=
"
2
"
>
\xa0
</td>
'
)
finally
:
spl_print_func
(
u
"
</tr>
\n
"
,
force
=
True
)
row_was_output
()
self
.
spl_print_func
(
u
"
</tr>
\n
"
,
force
=
True
)
self
.
row_was_output
()
m
=
orig1
and
re
.
match
(
r
"
^\[ (\d+) lines removed \]$
"
,
orig1
)
if
m
:
line1
+=
int
(
m
.
group
(
1
))
self
.
line1
+=
int
(
m
.
group
(
1
))
elif
orig1
:
line1
+=
1
self
.
line1
+=
1
m
=
orig2
and
re
.
match
(
r
"
^\[ (\d+) lines removed \]$
"
,
orig2
)
if
m
:
line2
+=
int
(
m
.
group
(
1
))
self
.
line2
+=
int
(
m
.
group
(
1
))
elif
orig2
:
line2
+=
1
self
.
line2
+=
1
def
empty_buffer
():
global
buf
global
add_cpt
global
del_cpt
def
empty_buffer
(
self
):
if
self
.
del_cpt
==
0
or
self
.
add_cpt
==
0
:
for
l
in
self
.
buf
:
self
.
output_line
(
l
[
0
],
l
[
1
])
if
del_cpt
==
0
or
add_cpt
==
0
:
for
l
in
buf
:
output_line
(
l
[
0
],
l
[
1
])
elif
del_cpt
!=
0
and
add_cpt
!=
0
:
elif
self
.
del_cpt
!=
0
and
self
.
add_cpt
!=
0
:
l0
,
l1
=
[],
[]
for
l
in
buf
:
for
l
in
self
.
buf
:
if
l
[
0
]
!=
None
:
l0
.
append
(
l
[
0
])
if
l
[
1
]
!=
None
:
...
...
@@ -246,241 +279,188 @@ def empty_buffer():
s0
=
l0
[
i
]
if
i
<
len
(
l1
):
s1
=
l1
[
i
]
output_line
(
s0
,
s1
)
add_cpt
,
del_cpt
=
0
,
0
buf
=
[]
self
.
output_line
(
s0
,
s1
)
self
.
add_cpt
=
0
self
.
del_cpt
=
0
self
.
buf
=
[]
def
spl_print_enter
(
print_context
,
rotation_params
):
def
spl_print_enter
(
self
,
print_context
,
rotation_params
):
# Takes ownership of print_context
global
spl_print_func
,
spl_print_ctrl
spl_print_ctrl
=
print_context
.
__exit__
,
rotation_params
spl_print_func
=
print_context
.
__enter__
()
self
.
spl_print_ctrl
=
print_context
.
__exit__
,
rotation_params
self
.
spl_print_func
=
print_context
.
__enter__
()
_
,
_
,
css_url
=
rotation_params
# Print file and table headers
output_header
(
css_url
,
spl_print_func
)
def
spl_had_entered_child
():
global
spl_print_ctrl
,
spl_current_page
return
spl_print_ctrl
and
spl_print_ctrl
[
1
]
and
spl_current_page
>
0
def
spl_print_exit
(
*
exc_info
):
global
spl_print_func
,
spl_print_ctrl
if
not
spl_had_entered_child
():
return
False
output_footer
(
spl_print_func
)
_exit
,
_
=
spl_print_ctrl
spl_print_func
,
spl_print_ctrl
=
None
,
None
return
_exit
(
*
exc_info
)
output_header
(
css_url
,
self
.
spl_print_func
)
@contextlib.contextmanager
def
spl_file_printer
(
directory
,
filename
):
with
codecs
.
open
(
os
.
path
.
join
(
directory
,
filename
),
'
w
'
,
encoding
=
'
utf-8
'
)
as
f
:
print_func
=
f
.
write
def
recording_print_func
(
s
,
force
=
False
):
print_func
(
s
)
recording_print_func
.
bytes_written
+=
len
(
s
)
recording_print_func
.
bytes_written
=
0
yield
recording_print_func
def
spl_had_entered_child
(
self
):
return
self
.
spl_print_ctrl
and
self
.
spl_print_ctrl
[
1
]
and
self
.
spl_current_page
>
0
def
spl_print_exit
(
self
,
*
exc_info
):
if
not
self
.
spl_had_entered_child
():
return
False
output_footer
(
self
.
spl_print_func
)
_exit
,
_
=
self
.
spl_print_ctrl
self
.
spl_print_func
=
None
self
.
spl_print_ctrl
=
None
return
_exit
(
*
exc_info
)
def
row_was_output
():
global
spl_print_func
,
spl_print_ctrl
,
spl_rows
,
spl_current_page
spl_rows
+=
1
_
,
rotation_params
=
spl_print_ctrl
def
row_was_output
(
self
):
self
.
spl_rows
+=
1
_
,
rotation_params
=
self
.
spl_print_ctrl
max_lines
=
Config
().
max_diff_block_lines
max_lines_parent
=
Config
().
max_diff_block_lines_parent
max_lines_ratio
=
Config
().
max_diff_block_lines_html_dir_ratio
max_report_child_size
=
Config
().
max_report_child_size
if
not
rotation_params
:
# html-dir single output, don't need to rotate
if
spl_rows
>=
max_lines
:
if
self
.
spl_rows
>=
max_lines
:
raise
DiffBlockLimitReached
()
return
else
:
# html-dir output, perhaps need to rotate
directory
,
mainname
,
css_url
=
rotation_params
if
spl_rows
>=
max_lines_ratio
*
max_lines
:
if
self
.
spl_rows
>=
max_lines_ratio
*
max_lines
:
raise
DiffBlockLimitReached
()
if
spl_current_page
==
0
:
# on parent page
if
spl_rows
<
max_lines_parent
:
if
self
.
spl_current_page
==
0
:
# on parent page
if
self
.
spl_rows
<
max_lines_parent
:
return
else
:
# on child page
# TODO: make this stay below the max, instead of going 1 row over the max
# will require some backtracking...
if
spl_print_func
.
bytes_written
<
max_report_child_size
:
if
self
.
spl_print_func
.
bytes_written
<
max_report_child_size
:
return
spl_current_page
+=
1
filename
=
"
%s-%s.html
"
%
(
mainname
,
spl_current_page
)
self
.
spl_current_page
+=
1
filename
=
"
%s-%s.html
"
%
(
mainname
,
self
.
spl_current_page
)
if
spl_current_page
>
1
:
if
self
.
spl_current_page
>
1
:
# previous page was a child, close it
spl_print_func
(
templates
.
UD_TABLE_FOOTER
%
{
"
filename
"
:
html
.
escape
(
filename
),
"
text
"
:
"
load diff
"
},
force
=
True
)
spl_print_exit
(
None
,
None
,
None
)
self
.
spl_print_func
(
templates
.
UD_TABLE_FOOTER
%
{
"
filename
"
:
html
.
escape
(
filename
),
"
text
"
:
"
load diff
"
},
force
=
True
)
self
.
spl_print_exit
(
None
,
None
,
None
)
# rotate to the next child page
context
=
spl_file_printer
(
directory
,
filename
)
spl_print_enter
(
context
,
rotation_params
)
spl_print_func
(
templates
.
UD_TABLE_HEADER
)
self
.
spl_print_enter
(
context
,
rotation_params
)
self
.
spl_print_func
(
templates
.
UD_TABLE_HEADER
)
def
output_unified_diff_table
(
unified_diff
,
_has_internal_linenos
):
global
add_cpt
,
del_cpt
global
line1
,
line2
,
has_internal_linenos
global
hunk_off1
,
hunk_size1
,
hunk_off2
,
hunk_size2
has_internal_linenos
=
_has_internal_linenos
spl_print_func
(
templates
.
UD_TABLE_HEADER
)
def
output_unified_diff_table
(
self
,
unified_diff
,
has_internal_linenos
):
self
.
has_internal_linenos
=
has_internal_linenos
self
.
spl_print_func
(
templates
.
UD_TABLE_HEADER
)
try
:
bytes_processed
=
0
for
l
in
unified_diff
.
splitlines
():
bytes_processed
+=
len
(
l
)
+
1
m
=
re
.
match
(
r
'
^--- ([^\s]*)
'
,
l
)
if
m
:
empty_buffer
()
self
.
empty_buffer
()
continue
m
=
re
.
match
(
r
'
^\+\+\+ ([^\s]*)
'
,
l
)
if
m
:
empty_buffer
()
self
.
empty_buffer
()
continue
m
=
re
.
match
(
r
"
@@ -(\d+),?(\d*) \+(\d+),?(\d*)
"
,
l
)
if
m
:
empty_buffer
()
self
.
empty_buffer
()
hunk_data
=
map
(
lambda
x
:
x
==
""
and
1
or
int
(
x
),
m
.
groups
())
hunk_off1
,
hunk_size1
,
hunk_off2
,
hunk_size2
=
hunk_data
line1
,
line2
=
hunk_off1
,
hunk_off2
output_hunk
()
self
.
hunk_off1
,
self
.
hunk_size1
,
self
.
hunk_off2
,
self
.
hunk_size2
=
hunk_data
self
.
line1
,
self
.
line2
=
self
.
hunk_off1
,
self
.
hunk_off2
self
.
output_hunk
()
continue
if
re
.
match
(
r
'
^\[
'
,
l
):
empty_buffer
()
spl_print_func
(
u
'
<td colspan=
"
2
"
>%s</td>
\n
'
%
l
)
self
.
empty_buffer
()
self
.
spl_print_func
(
u
'
<td colspan=
"
2
"
>%s</td>
\n
'
%
l
)
if
re
.
match
(
r
"
^\\ No newline
"
,
l
):
if
hunk_size2
==
0
:
buf
[
-
1
]
=
(
buf
[
-
1
][
0
],
buf
[
-
1
][
1
]
+
'
\n
'
+
l
[
2
:])
if
self
.
hunk_size2
==
0
:
self
.
buf
[
-
1
]
=
(
self
.
buf
[
-
1
][
0
],
self
.
buf
[
-
1
][
1
]
+
'
\n
'
+
l
[
2
:])
else
:
buf
[
-
1
]
=
(
buf
[
-
1
][
0
]
+
'
\n
'
+
l
[
2
:],
buf
[
-
1
][
1
])
self
.
buf
[
-
1
]
=
(
buf
[
-
1
][
0
]
+
'
\n
'
+
l
[
2
:],
self
.
buf
[
-
1
][
1
])
continue
if
hunk_size1
<=
0
and
hunk_size2
<=
0
:
empty_buffer
()
if
self
.
hunk_size1
<=
0
and
self
.
hunk_size2
<=
0
:
self
.
empty_buffer
()
continue
m
=
re
.
match
(
r
"
^\+\[ (\d+) lines removed \]$
"
,
l
)
if
m
:
add_cpt
+=
int
(
m
.
group
(
1
))
hunk_size2
-=
int
(
m
.
group
(
1
))
buf
.
append
((
None
,
l
[
1
:]))
self
.
add_cpt
+=
int
(
m
.
group
(
1
))
self
.
hunk_size2
-=
int
(
m
.
group
(
1
))
self
.
buf
.
append
((
None
,
l
[
1
:]))
continue
if
re
.
match
(
r
"
^\+
"
,
l
):
add_cpt
+=
1
hunk_size2
-=
1
buf
.
append
((
None
,
l
[
1
:]))
self
.
add_cpt
+=
1
self
.
hunk_size2
-=
1
self
.
buf
.
append
((
None
,
l
[
1
:]))
continue
m
=
re
.
match
(
r
"
^-\[ (\d+) lines removed \]$
"
,
l
)
if
m
:
del_cpt
+=
int
(
m
.
group
(
1
))
hunk_size1
-=
int
(
m
.
group
(
1
))
buf
.
append
((
l
[
1
:],
None
))
self
.
del_cpt
+=
int
(
m
.
group
(
1
))
self
.
hunk_size1
-=
int
(
m
.
group
(
1
))
self
.
buf
.
append
((
l
[
1
:],
None
))
continue
if
re
.
match
(
r
"
^-
"
,
l
):
del_cpt
+=
1
hunk_size1
-=
1
buf
.
append
((
l
[
1
:],
None
))
self
.
del_cpt
+=
1
self
.
hunk_size1
-=
1
self
.
buf
.
append
((
l
[
1
:],
None
))
continue
if
re
.
match
(
r
"
^
"
,
l
)
and
hunk_size1
and
hunk_size2
:
empty_buffer
()
hunk_size1
-=
1
hunk_size2
-=
1
buf
.
append
((
l
[
1
:],
l
[
1
:]))
if
re
.
match
(
r
"
^
"
,
l
)
and
self
.
hunk_size1
and
self
.
hunk_size2
:
self
.
empty_buffer
()
self
.
hunk_size1
-=
1
self
.
hunk_size2
-=
1
self
.
buf
.
append
((
l
[
1
:],
l
[
1
:]))
continue
empty_buffer
()
self
.
empty_buffer
()
empty_buffer
()
self
.
empty_buffer
()
return
True
except
DiffBlockLimitReached
:
total
=
len
(
unified_diff
)
bytes_left
=
total
-
bytes_processed
frac
=
bytes_left
/
total
spl_print_func
(
self
.
spl_print_func
(
u
'
<tr class=
"
error
"
>
'
u
'
<td colspan=
"
4
"
>Max diff block lines reached; %s/%s bytes (%.2f%%) of diff not shown.
'
u
"
</td></tr>
"
%
(
bytes_left
,
total
,
frac
*
100
),
force
=
True
)
return
False
except
PrintLimitReached
:
assert
not
spl_had_entered_child
()
# limit reached on the parent page
spl_print_func
(
u
'
<tr class=
"
error
"
><td colspan=
"
4
"
>Max output size reached.</td></tr>
'
,
force
=
True
)
assert
not
self
.
spl_had_entered_child
()
# limit reached on the parent page
self
.
spl_print_func
(
u
'
<tr class=
"
error
"
><td colspan=
"
4
"
>Max output size reached.</td></tr>
'
,
force
=
True
)
raise
finally
:
spl_print_func
(
u
"
</table>
"
,
force
=
True
)
self
.
spl_print_func
(
u
"
</table>
"
,
force
=
True
)
def
output_unified_diff
(
print_func
,
css_url
,
directory
,
unified_diff
,
has_internal_linenos
):
global
spl_print_func
,
spl_print_ctrl
,
spl_current_page
new_unified_diff
()
def
output_unified_diff
(
self
,
print_func
,
css_url
,
directory
,
unified_diff
,
has_internal_linenos
):
self
.
new_unified_diff
()
rotation_params
=
None
if
directory
:
mainname
=
hashlib
.
md5
(
unified_diff
.
encode
(
'
utf-8
'
)).
hexdigest
()
rotation_params
=
directory
,
mainname
,
css_url
try
:
spl_print_func
=
print_func
spl_print_ctrl
=
None
,
rotation_params
truncated
=
not
output_unified_diff_table
(
unified_diff
,
has_internal_linenos
)
self
.
spl_print_func
=
print_func
self
.
spl_print_ctrl
=
None
,
rotation_params
truncated
=
not
self
.
output_unified_diff_table
(
unified_diff
,
has_internal_linenos
)
except
:
if
not
spl_print_exit
(
*
sys
.
exc_info
()):
raise
if
not
self
.
spl_print_exit
(
*
sys
.
exc_info
()):
raise
else
:
spl_print_exit
(
None
,
None
,
None
)
self
.
spl_print_exit
(
None
,
None
,
None
)
finally
:
spl_print_ctrl
=
None
spl_print_func
=
None
self
.
spl_print_ctrl
=
None
self
.
spl_print_func
=
None
if
spl_current_page
>
0
:
noun
=
"
pieces
"
if
spl_current_page
>
1
else
"
piece
"
text
=
"
load diff (%s %s%s)
"
%
(
spl_current_page
,
noun
,
(
"
, truncated
"
if
truncated
else
""
))
if
self
.
spl_current_page
>
0
:
noun
=
"
pieces
"
if
self
.
spl_current_page
>
1
else
"
piece
"
text
=
"
load diff (%s %s%s)
"
%
(
self
.
spl_current_page
,
noun
,
(
"
, truncated
"
if
truncated
else
""
))
print_func
(
templates
.
UD_TABLE_FOOTER
%
{
"
filename
"
:
html
.
escape
(
"
%s-1.html
"
%
mainname
),
"
text
"
:
text
},
force
=
True
)
def
output_visual
(
print_func
,
visual
,
parents
):
logger
.
debug
(
'
including image for %s
'
,
visual
.
source
)
sources
=
parents
+
[
visual
.
source
]
print_func
(
u
'
<div class=
"
difference
"
>
'
)
print_func
(
u
'
<div class=
"
diffheader
"
>
'
)
print_func
(
u
'
<div class=
"
diffcontrol
"
>⊟</div>
'
)
print_func
(
u
'
<div><span class=
"
source
"
>%s</span>
'
%
html
.
escape
(
visual
.
source
))
anchor
=
escape_anchor
(
'
/
'
.
join
(
sources
[
1
:]))
print_func
(
u
'
<a class=
"
anchor
"
href=
"
#%s
"
name=
"
%s
"
>
\xb6
</a>
'
%
(
anchor
,
anchor
))
print_func
(
u
"
</div>
"
)
print_func
(
u
"
</div>
"
)
print_func
(
u
'
<div class=
"
difference
"
>
'
u
'
<img src=
\"
data:%s,%s
\"
alt=
\"
compared images
\"
/></div>
'
%
(
visual
.
data_type
,
visual
.
content
))
print_func
(
u
"
</div>
"
,
force
=
True
)
def
escape_anchor
(
val
):
"""
ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed
by any number of letters, digits ([0-9]), hyphens (
"
-
"
), underscores (
"
_
"
),
colons (
"
:
"
), and periods (
"
.
"
).
"""
for
pattern
,
repl
in
(
(
re_anchor_prefix
,
'
D
'
),
(
re_anchor_suffix
,
'
-
'
),
):
val
=
pattern
.
sub
(
repl
,
val
)
return
val
def
output_difference
(
difference
,
print_func
,
css_url
,
directory
,
parents
):
def
output_difference
(
self
,
difference
,
print_func
,
css_url
,
directory
,
parents
):
logger
.
debug
(
'
html output for %s
'
,
difference
.
source1
)
sources
=
parents
+
[
difference
.
source1
]
print_func
(
u
'
<div class=
"
difference
"
>
'
)
...
...
@@ -508,31 +488,16 @@ def output_difference(difference, print_func, css_url, directory, parents):
for
visual
in
difference
.
visuals
:
output_visual
(
print_func
,
visual
,
sources
)
elif
difference
.
unified_diff
:
output_unified_diff
(
print_func
,
css_url
,
directory
,
difference
.
unified_diff
,
difference
.
has_internal_linenos
)
self
.
output_unified_diff
(
print_func
,
css_url
,
directory
,
difference
.
unified_diff
,
difference
.
has_internal_linenos
)
for
detail
in
difference
.
details
:
output_difference
(
detail
,
print_func
,
css_url
,
directory
,
sources
)
self
.
output_difference
(
detail
,
print_func
,
css_url
,
directory
,
sources
)
except
PrintLimitReached
:
logger
.
debug
(
'
print limit reached
'
)
raise
finally
:
print_func
(
u
"
</div>
"
,
force
=
True
)
def
output_header
(
css_url
,
print_func
):
if
css_url
:
css_link
=
'
<link href=
"
%s
"
type=
"
text/css
"
rel=
"
stylesheet
"
/>
'
%
css_url
else
:
css_link
=
''
print_func
(
templates
.
HEADER
%
{
'
title
'
:
html
.
escape
(
'
'
.
join
(
sys
.
argv
)),
'
favicon
'
:
FAVICON_BASE64
,
'
css_link
'
:
css_link
,
})
def
output_footer
(
print_func
):
print_func
(
templates
.
FOOTER
%
{
'
version
'
:
VERSION
},
force
=
True
)
def
output_html
(
difference
,
css_url
=
None
,
print_func
=
None
):
def
output_html
(
self
,
difference
,
css_url
=
None
,
print_func
=
None
):
"""
Default presenter, all in one HTML file
"""
...
...
@@ -541,19 +506,26 @@ def output_html(difference, css_url=None, print_func=None):
print_func
=
create_limited_print_func
(
print_func
,
Config
().
max_report_size
)
try
:
output_header
(
css_url
,
print_func
)
output_difference
(
difference
,
print_func
,
css_url
,
None
,
[])
self
.
output_difference
(
difference
,
print_func
,
css_url
,
None
,
[])
except
PrintLimitReached
:
logger
.
debug
(
'
print limit reached
'
)
print_func
(
u
'
<div class=
"
error
"
>Max output size reached.</div>
'
,
force
=
True
)
output_footer
(
print_func
)
@contextlib.contextmanager
def
file_printer
(
directory
,
filename
):
with
codecs
.
open
(
os
.
path
.
join
(
directory
,
filename
),
'
w
'
,
encoding
=
'
utf-8
'
)
as
f
:
yield
f
.
write
@classmethod
def
run
(
cls
,
data
,
difference
,
parsed_args
):
with
make_printer
(
parsed_args
.
html_output
)
as
fn
:
cls
().
output_html
(
difference
,
css_url
=
parsed_args
.
css_url
,
print_func
=
fn
,
)
def
output_html_directory
(
directory
,
difference
,
css_url
=
None
,
jquery_url
=
None
):
class
HTMLDirectoryPresenter
(
HTMLPresenter
):
def
output_html_directory
(
self
,
directory
,
difference
,
css_url
=
None
,
jquery_url
=
None
):
"""
Multi-file presenter. Writes to a directory, and puts large diff tables
into files of their own.
...
...
@@ -590,7 +562,7 @@ def output_html_directory(directory, difference, css_url=None, jquery_url=None):
print_func
=
create_limited_print_func
(
print_func
,
Config
().
max_report_size
)
try
:
output_header
(
css_url
,
print_func
)
output_difference
(
difference
,
print_func
,
css_url
,
directory
,
[])
self
.
output_difference
(
difference
,
print_func
,
css_url
,
directory
,
[])
except
PrintLimitReached
:
logger
.
debug
(
'
print limit reached
'
)
print_func
(
u
'
<div class=
"
error
"
>Max output size reached.</div>
'
,
...
...
@@ -598,3 +570,12 @@ def output_html_directory(directory, difference, css_url=None, jquery_url=None):
if
jquery_url
:
print_func
(
templates
.
SCRIPTS
%
{
'
jquery_url
'
:
html
.
escape
(
jquery_url
)},
force
=
True
)
output_footer
(
print_func
)
@classmethod
def
run
(
cls
,
data
,
difference
,
parsed_args
):
cls
().
output_html_directory
(
parsed_args
.
html_output_directory
,
difference
,
css_url
=
parsed_args
.
css_url
,
jquery_url
=
parsed_args
.
jquery_url
,
)
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment