Skip to content

Commit

Permalink
Merge branch 'feature/text-render-size-limits' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
felliott committed Oct 20, 2016
2 parents 6a06849 + 1949f93 commit 489e72a
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 1 deletion.
6 changes: 6 additions & 0 deletions mfr/extensions/codepygments/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from mfr.core.exceptions import RendererError


class FileTooLargeException(RendererError):
def __init__(self, *args, **kwargs):
super().__init__(code=400, *args, **kwargs)
10 changes: 10 additions & 0 deletions mfr/extensions/codepygments/render.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os

import chardet
from humanfriendly import format_size
import pygments
import pygments.lexers
import pygments.lexers.special
Expand All @@ -9,6 +10,8 @@
from mako.lookup import TemplateLookup

from mfr.core import extension, exceptions
from mfr.extensions.codepygments import settings
from mfr.extensions.codepygments import exceptions as cp_exceptions


class CodePygmentsRenderer(extension.BaseRenderer):
Expand All @@ -25,6 +28,13 @@ def __init__(self, *args, **kwargs):
self.metrics.add('pygments_version', pygments.__version__)

def render(self):
file_size = os.path.getsize(self.file_path)
if file_size > settings.MAX_SIZE:
raise cp_exceptions.FileTooLargeException(
'Text files larger than {} are not rendered. Please download the file to '
'view.'.format(format_size(settings.MAX_SIZE, binary=True))
)

with open(self.file_path, 'rb') as fp:
body = self._render_html(fp, self.metadata.ext)
return self.TEMPLATE.render(base=self.assets_url, body=body)
Expand Down
5 changes: 5 additions & 0 deletions mfr/extensions/codepygments/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from mfr import settings

config = settings.child('CODEPYGMENTS_EXTENSION_CONFIG')

MAX_SIZE = int(config.get('MAX_SIZE', 65536))
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
aiohttp==0.18.4
chardet==2.3.0
furl==0.4.2
humanfriendly==2.1
invoke==0.11.1
mako==1.0.1
raven==5.27.0
Expand Down
44 changes: 43 additions & 1 deletion tests/extensions/codepygments/test_renderer.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import os
import pytest
from tempfile import NamedTemporaryFile

from mfr.core.exceptions import RendererError
from mfr.core.provider import ProviderMetadata

from mfr.extensions.codepygments import CodePygmentsRenderer
from mfr.extensions.codepygments import settings, CodePygmentsRenderer
from mfr.extensions.codepygments.exceptions import FileTooLargeException


@pytest.fixture
Expand All @@ -16,6 +18,29 @@ def metadata():
def test_file_path():
return os.path.join(os.path.dirname(os.path.abspath(__file__)), 'files', 'test.xml')

@pytest.fixture
def max_size_file_path():
dir_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
'files')
with NamedTemporaryFile(mode='w+b', suffix='.txt', dir=dir_path,
delete=False) as temp_file:
temp_file_path = temp_file.name
file_size = settings.MAX_SIZE
temp_file.seek(file_size -1)
temp_file.write(b'0')
return temp_file_path

@pytest.fixture
def over_size_file_path():
dir_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
'files')
with NamedTemporaryFile(mode='w+b', suffix='.txt', dir=dir_path,
delete=False) as temp_file:
temp_file_path = temp_file.name
file_size = settings.MAX_SIZE
temp_file.seek(file_size)
temp_file.write(b'0')
return temp_file_path

@pytest.fixture
def invalid_file_path():
Expand Down Expand Up @@ -58,6 +83,23 @@ def test_render_codepygments_invalid(self, metadata, invalid_file_path, url, ass
with pytest.raises(RendererError):
renderer.render()

def test_render_codepygments_max_size(self, metadata, max_size_file_path, url, assets_url, export_url):
try:
renderer = CodePygmentsRenderer(metadata, max_size_file_path, url, assets_url, export_url)
body = renderer.render()
assert '<div style="word-wrap: break-word;" class="mfrViewer">' in body
finally:
os.remove(max_size_file_path)

def test_render_codepygments_over_size(self, metadata, over_size_file_path, url, assets_url, export_url):
with pytest.raises(FileTooLargeException):
try:
renderer = CodePygmentsRenderer(metadata, over_size_file_path,
url, assets_url, export_url)
renderer.render()
finally:
os.remove(over_size_file_path)

def test_render_codepygments_file_required(self, renderer):
assert renderer.file_required is True

Expand Down

0 comments on commit 489e72a

Please sign in to comment.