Skip to content
Snippets Groups Projects
Unverified Commit a8aa2c84 authored by Dan Granville's avatar Dan Granville Committed by GitHub
Browse files

txt-preview: improvements (#180)


* enable horizontal scrolling
* add option to truncate .txt file preview after PREVIEWER_TXT_MAX_BYTES
* avoid possible invalid encoding errors

Co-authored-by: default avatarGuillaume Viger <fenekku@fenekku.com>
parent cd63d8da
No related branches found
No related tags found
No related merge requests found
#text-previewer {
padding: 0.5em;
}
...@@ -26,6 +26,9 @@ PREVIEWER_MAX_FILE_SIZE_BYTES = 1 * 1024 * 1024 ...@@ -26,6 +26,9 @@ PREVIEWER_MAX_FILE_SIZE_BYTES = 1 * 1024 * 1024
PREVIEWER_MAX_IMAGE_SIZE_BYTES = 0.5 * 1024 * 1024 PREVIEWER_MAX_IMAGE_SIZE_BYTES = 0.5 * 1024 * 1024
"""Maximum file size in bytes for image files.""" """Maximum file size in bytes for image files."""
PREVIEWER_TXT_MAX_BYTES = 1 * 1024 * 1024
"""Maximum number of .txt file bytes to preview before truncated."""
PREVIEWER_ZIP_MAX_FILES = 1000 PREVIEWER_ZIP_MAX_FILES = 1000
"""Max number of files showed in the ZIP previewer.""" """Max number of files showed in the ZIP previewer."""
......
...@@ -8,19 +8,20 @@ ...@@ -8,19 +8,20 @@
"""Text rendering.""" """Text rendering."""
from flask import render_template from flask import current_app, render_template
from ..proxies import current_previewer from ..proxies import current_previewer
from ..utils import detect_encoding from ..utils import detect_encoding
previewable_extensions = ["txt"] previewable_extensions = ["txt"]
max_bytes = current_app.config.get('PREVIEWER_TXT_MAX_BYTES', -1)
def render(file): def render(file):
"""Render HTML from txt file content.""" """Render HTML from txt file content."""
with file.open() as fp: with file.open() as fp:
encoding = detect_encoding(fp, default="utf-8") encoding = detect_encoding(fp, default="utf-8")
return fp.read().decode(encoding) return fp.read(max_bytes).decode(encoding, errors="ignore")
def can_preview(file): def can_preview(file):
...@@ -37,5 +38,6 @@ def preview(file): ...@@ -37,5 +38,6 @@ def preview(file):
file=file, file=file,
content=render(file), content=render(file),
js_bundles=current_previewer.js_bundles, js_bundles=current_previewer.js_bundles,
css_bundles=current_previewer.css_bundles, css_bundles=['txt_css.css'],
truncated=max_bytes < file.size,
) )
...@@ -10,11 +10,10 @@ ...@@ -10,11 +10,10 @@
{%- extends config.PREVIEWER_ABSTRACT_TEMPLATE %} {%- extends config.PREVIEWER_ABSTRACT_TEMPLATE %}
{% block panel %} {% block panel %}
<div class="ui container"> <div id="text-previewer">
<div class="ui grid column">
<div class="column">
<pre>{{ content }}</pre> <pre>{{ content }}</pre>
</div> {% if truncated %}
</div> <hr /><div class="banner">{{ _('Preview of large file truncated') }}</div>
{% endif %}
</div> </div>
{% endblock %} {% endblock %}
...@@ -75,6 +75,7 @@ previewer = WebpackThemeBundle( ...@@ -75,6 +75,7 @@ previewer = WebpackThemeBundle(
'bottom_css': './scss/invenio_previewer/bottom.scss', 'bottom_css': './scss/invenio_previewer/bottom.scss',
'simple_image_css': 'simple_image_css':
'./scss/invenio_previewer/simple_image.scss', './scss/invenio_previewer/simple_image.scss',
'txt_css': './scss/invenio_previewer/txt.scss',
}, },
dependencies={ dependencies={
'd3': '^3.5.17', 'd3': '^3.5.17',
......
...@@ -232,6 +232,24 @@ def test_simple_image_extension(app, webassets, record): ...@@ -232,6 +232,24 @@ def test_simple_image_extension(app, webassets, record):
assert 'class="previewer-simple-image"' in res.get_data(as_text=True) assert 'class="previewer-simple-image"' in res.get_data(as_text=True)
def test_txt_extension(app, webassets, record):
"""Text .txt file viewer."""
create_file(record, 'test1.txt', BytesIO(b'test content foobar'))
with app.test_client() as client:
res = client.get(preview_url(record['control_number'], 'test1.txt'))
assert "<pre>test content foobar</pre>" in res.get_data(as_text=True)
max_file_size = app.config.get(
'PREVIEWER_TXT_MAX_BYTES', 1 * 1024 * 1024)
too_large_string = '1' * (max_file_size + 1)
create_file(record, 'test2.txt', BytesIO(b(too_large_string)))
with app.test_client() as client:
res = client.get(preview_url(record['control_number'], 'test1.txt'))
assert "file truncated" in res.get_data(as_text=True)
def test_view_macro_file_list(app): def test_view_macro_file_list(app):
"""Test file list macro.""" """Test file list macro."""
with app.test_request_context(): with app.test_request_context():
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment