Skip to content

Commit 87d6c55

Browse files
committed
Merge branch 'release/19.0.0'
2 parents 291ed72 + ebe6f18 commit 87d6c55

File tree

14 files changed

+164
-132
lines changed

14 files changed

+164
-132
lines changed

CHANGELOG

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22
ChangeLog
33
*********
44

5+
19.0.0 (2019-06-19)
6+
===================
7+
- Fix: Add white background to transparent .gifs to improve zooming appearance. The zooming code
8+
keeps a copy of the image behind the zoomed version to improve performance. If the image is
9+
transparent the actual-size copy will be visible behind the zoomed version. Making the background
10+
opaque hides the original.
11+
- Feature: Track when the hypothes.is sidebar is opened via Google Analytics. (thanks, @adlius!)
12+
- Feature: Add timeouts to renderers that shell out to external processes for conversion. If a
13+
conversion takes longer than the configured number of seconds, MFR will return an error message
14+
instead of waiting forever. (thanks, @ExProbitasFiducia!)
15+
- Code: Remove Rackspace cache-management tasks. MFR is now hosted on GoogleCloud, and these are no
16+
longer needed. (thanks, @ExProbitasFiducia!)
17+
518
18.0.0 (2018-10-11)
619
===================
720
- UPDATE: MFR is now following the CalVer (https://calver.org/) versioning scheme to match the

Dockerfile

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM python:3.5-slim-jessie
1+
FROM python:3.5-slim-stretch
22

33
# ensure unoconv can locate the uno library
44
ENV PYTHONPATH=/usr/lib/python3/dist-packages
@@ -18,7 +18,7 @@ RUN usermod -d /home www-data \
1818
libevent-dev \
1919
libfreetype6-dev \
2020
libjpeg-dev \
21-
libpng12-dev \
21+
libpng-dev \
2222
libtiff5-dev \
2323
libxml2-dev \
2424
libxslt1-dev \
@@ -32,14 +32,13 @@ RUN usermod -d /home www-data \
3232
gnupg2 \
3333
# gosu
3434
&& export GOSU_VERSION='1.10' \
35-
&& for key in \
36-
# GOSU
37-
B42F6819007F00F88E364FD4036A9C25BF357DD4 \
35+
&& mkdir ~/.gnupg && chmod 600 ~/.gnupg && echo "disable-ipv6" >> ~/.gnupg/dirmngr.conf \
36+
&& for server in hkp://ipv4.pool.sks-keyservers.net:80 \
37+
hkp://ha.pool.sks-keyservers.net:80 \
38+
hkp://pgp.mit.edu:80 \
39+
hkp://keyserver.pgp.com:80 \
3840
; do \
39-
gpg --keyserver hkp://ipv4.pool.sks-keyservers.net:80 --recv-keys "$key" || \
40-
gpg --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-keys "$key" || \
41-
gpg --keyserver hkp://pgp.mit.edu:80 --recv-keys "$key" || \
42-
gpg --keyserver hkp://keyserver.pgp.com:80 --recv-keys "$key" \
41+
gpg --keyserver "$server" --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 && break || echo "Trying new server..." \
4342
; done \
4443
&& curl -o /usr/local/bin/gosu -SL "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \
4544
&& curl -o /usr/local/bin/gosu.asc -SL "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \
@@ -50,29 +49,38 @@ RUN usermod -d /home www-data \
5049
&& apt-get clean \
5150
&& apt-get autoremove -y \
5251
curl \
52+
gnupg2 \
5353
&& rm -rf /var/lib/apt/lists/* \
5454
&& pip install -U pip \
5555
&& pip install setuptools==37.0.0 \
5656
&& mkdir -p /code
5757

58-
ENV LIBREOFFICE_VERSION 6.0.2.1
59-
ENV LIBREOFFICE_ARCHIVE LibreOffice_6.0.2.1_Linux_x86-64_deb.tar.gz
60-
ENV LIBREOFFICE_MIRROR_URL https://downloadarchive.documentfoundation.org/libreoffice/old/
58+
ENV LIBREOFFICE_VERSION 6.1.5
59+
ENV LIBREOFFICE_ARCHIVE LibreOffice_6.1.5_Linux_x86-64_deb.tar.gz
60+
ENV LIBREOFFICE_MIRROR_URL https://download.documentfoundation.org/libreoffice/stable/
6161
RUN apt-get update \
6262
&& apt-get install -y \
6363
curl \
64-
&& gpg --keyserver pool.sks-keyservers.net --recv-keys AFEEAEA3 \
64+
gnupg2 \
65+
&& for server in hkp://ipv4.pool.sks-keyservers.net:80 \
66+
hkp://ha.pool.sks-keyservers.net:80 \
67+
hkp://pgp.mit.edu:80 \
68+
hkp://keyserver.pgp.com:80 \
69+
; do \
70+
gpg --keyserver "$server" --recv-keys AFEEAEA3 && break || echo "Trying new server..." \
71+
; done \
6572
&& curl -SL "$LIBREOFFICE_MIRROR_URL/$LIBREOFFICE_VERSION/deb/x86_64/$LIBREOFFICE_ARCHIVE" -o $LIBREOFFICE_ARCHIVE \
66-
&& curl -SL "$LIBREOFFICE_MIRROR_URL/$LIBREOFFICE_VERSION/deb/x86_64/$LIBREOFFICE_ARCHIVE.asc" -o $LIBREOFFICE_ARCHIVE.asc \
67-
&& gpg --verify "$LIBREOFFICE_ARCHIVE.asc" \
68-
&& mkdir /tmp/libreoffice \
69-
&& tar -xvf "$LIBREOFFICE_ARCHIVE" -C /tmp/libreoffice/ --strip-components=1 \
70-
&& dpkg -i /tmp/libreoffice/**/*.deb \
71-
&& rm $LIBREOFFICE_ARCHIVE* \
72-
&& rm -Rf /tmp/libreoffice \
73+
&& curl -SL "$LIBREOFFICE_MIRROR_URL/$LIBREOFFICE_VERSION/deb/x86_64/$LIBREOFFICE_ARCHIVE.asc" -o $LIBREOFFICE_ARCHIVE.asc \
74+
&& gpg --verify "$LIBREOFFICE_ARCHIVE.asc" \
75+
&& mkdir /tmp/libreoffice \
76+
&& tar -xvf "$LIBREOFFICE_ARCHIVE" -C /tmp/libreoffice/ --strip-components=1 \
77+
&& dpkg -i /tmp/libreoffice/**/*.deb \
78+
&& rm $LIBREOFFICE_ARCHIVE* \
79+
&& rm -Rf /tmp/libreoffice \
7380
&& apt-get clean \
7481
&& apt-get autoremove -y \
7582
curl \
83+
gnupg2 \
7684
&& rm -rf /var/lib/apt/lists/*
7785

7886
RUN pip install unoconv==0.8.2

mfr/extensions/image/static/js/jquery.zoom.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
* Original Copy: https://github.com/jackmoore/zoom/blob/1.7.20/jquery.zoom.js
55
* Version: https://github.com/jackmoore/zoom/releases/tag/1.7.20
66
*
7-
* The are two MFR customizations in this file, one for style and one for functionality
7+
* The are three MFR customizations in this file, two for style and one for functionality
88
*
99
* 1. Updated code style according to `.eslintrc.js`
1010
* 2. Added `.on("mousewheel", function (e) { ... })` to enable further zoom by mouse wheel scroll
11+
* 3. Set "background-color: white" for "zoomImage" to handle images with transparent background
1112
*/
1213

1314
(function ($) {
@@ -53,6 +54,7 @@
5354
top: 0,
5455
left: 0,
5556
opacity: 0,
57+
"background-color": "white",
5658
width: img.width * magnify,
5759
height: img.height * magnify,
5860
border: "none",

mfr/extensions/jsc3d/export.py

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1-
import os
21
import shutil
3-
import subprocess
42
from http import HTTPStatus
3+
from subprocess import (DEVNULL,
4+
check_call,
5+
TimeoutExpired,
6+
CalledProcessError)
7+
from os.path import basename, splitext
58
from tempfile import NamedTemporaryFile
69

710
from mfr.core import exceptions
811
from mfr.core.extension import BaseExporter
9-
from mfr.extensions.jsc3d.settings import (FREECAD_BIN,
10-
FREECAD_CONVERT_SCRIPT)
12+
from mfr.extensions.jsc3d.settings import (TIMEOUT,
13+
FREECAD_BIN,
14+
CONVERSION_SCRIPT)
1115

1216

1317
class JSC3DExporter(BaseExporter):
@@ -22,16 +26,14 @@ def export(self):
2226
temp_source_file.name = self.source_file_path + '.step'
2327
shutil.copy2(self.source_file_path, temp_source_file.name)
2428

25-
subprocess.check_call([
26-
FREECAD_BIN,
27-
FREECAD_CONVERT_SCRIPT,
28-
temp_source_file.name,
29-
self.output_file_path,
30-
# silence output from freecadcmd
31-
], stdout=subprocess.DEVNULL)
29+
check_call(
30+
[FREECAD_BIN, CONVERSION_SCRIPT, temp_source_file.name, self.output_file_path],
31+
stdout=DEVNULL, # silence output from freecadcmd
32+
timeout=TIMEOUT,
33+
)
3234

33-
except subprocess.CalledProcessError as err:
34-
name, extension = os.path.splitext(os.path.split(self.source_file_path)[-1])
35+
except CalledProcessError as err:
36+
name, extension = splitext(basename(self.source_file_path))
3537
raise exceptions.SubprocessError(
3638
'Unable to export the file in the requested format, please try again later.',
3739
process='freecad',
@@ -42,3 +44,19 @@ def export(self):
4244
extension=extension or '',
4345
exporter_class='jsc3d',
4446
)
47+
48+
except TimeoutExpired as err:
49+
name, extension = splitext(basename(self.source_file_path))
50+
# The return code 52 is not the error code returned by the
51+
# subprocess, but the error given to it by this waterbutler
52+
# processs, for timing out.
53+
raise exceptions.SubprocessError(
54+
'JSC3D Conversion timed out.',
55+
code=HTTPStatus.GATEWAY_TIMEOUT,
56+
process='freecad',
57+
cmd=str(err.cmd),
58+
returncode=52,
59+
path=str(self.source_file_path),
60+
extension=extension or '',
61+
exporter_class='jsc3d'
62+
)

mfr/extensions/jsc3d/settings.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
config = settings.child('JSC3D_EXTENSION_CONFIG')
44

55
FREECAD_BIN = config.get('FREECAD_BIN', '/usr/bin/freecadcmd')
6-
FREECAD_CONVERT_SCRIPT = config.get('FREECAD_CONVERT_SCRIPT', '/code/mfr/extensions/jsc3d/freecad_converter.py')
6+
CONVERSION_SCRIPT = config.get('FREECAD_CONVERT_SCRIPT', '/code/mfr/extensions/jsc3d/freecad_converter.py')
7+
TIMEOUT = int(config.get('FREECAD_TIMEOUT', 30)) # In seconds
78
EXPORT_TYPE = config.get('EXPORT_TYPE', '.stl')
89
EXPORT_EXCLUSIONS = config.get('EXPORT_EXCLUSIONS', '.3ds .stl .obj .ctm').split(' ')

mfr/extensions/pdf/render.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from mfr.core import extension
88
from mfr.extensions.pdf import settings
99
from mfr.extensions.utils import munge_url_for_localdev, escape_url_for_template
10+
from mfr.settings import GOOGLE_ANALYTICS_TRACKING_ID
1011

1112
logger = logging.getLogger(__name__)
1213

@@ -29,6 +30,7 @@ def render(self):
2930
if self.metadata.ext.lower() not in settings.EXPORT_SUPPORTED:
3031
logger.debug('Extension not found in supported list!')
3132
return self.TEMPLATE.render(
33+
ga_tracking_id=GOOGLE_ANALYTICS_TRACKING_ID,
3234
base=self.assets_url,
3335
url=escape_url_for_template(download_url.geturl()),
3436
stable_id=self.metadata.stable_id,
@@ -46,6 +48,7 @@ def render(self):
4648

4749
self.metrics.add('needs_export', True)
4850
return self.TEMPLATE.render(
51+
ga_tracking_id=GOOGLE_ANALYTICS_TRACKING_ID,
4952
base=self.assets_url,
5053
url=escape_url_for_template(exported_url.url),
5154
stable_id=self.metadata.stable_id,

mfr/extensions/pdf/templates/viewer.mako

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,12 @@ http://sourceforge.net/adobe/cmap/wiki/License/
426426
<script>
427427
window.MFR_STABLE_ID = '${stable_id}';
428428
window.MFR_FILE_NAME = '${file_name}';
429+
window.GA_TRACKING_ID = '${ga_tracking_id}';
430+
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
431+
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
432+
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
433+
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
434+
ga('create', window.GA_TRACKING_ID, 'auto');
429435
</script>
430436
<script src="/static/js/mfr.child.hypothesis.js"></script>
431437
% endif

mfr/extensions/tabular/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@
3737
})
3838

3939
PSPP_CONVERT_BIN = config.get('PSPP_CONVERT_BIN', '/usr/bin/pspp-convert')
40+
PSPP_CONVERT_TIMEOUT = int(config.get('PSPP_CONVERT_TIMEOUT', 30)) # In seconds

mfr/extensions/tabular/utilities.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import re
2-
import subprocess
2+
from http import HTTPStatus
3+
from subprocess import (check_call,
4+
TimeoutExpired,
5+
CalledProcessError)
36
from tempfile import NamedTemporaryFile
47

5-
from mfr.core import exceptions
6-
from mfr.extensions.tabular import compat, settings
8+
from mfr.extensions.tabular import compat
9+
from mfr.core.exceptions import SubprocessError
10+
from mfr.extensions.tabular.settings import (PSPP_CONVERT_BIN,
11+
PSPP_CONVERT_TIMEOUT)
712

813

914
def header_population(headers):
@@ -48,20 +53,33 @@ def sav_to_csv(fp):
4853
"""
4954
csv_file = NamedTemporaryFile(mode='w+b', suffix='.csv')
5055
try:
51-
subprocess.check_call([
52-
settings.PSPP_CONVERT_BIN,
53-
fp.name,
54-
csv_file.name,
55-
])
56-
except subprocess.CalledProcessError as err:
57-
raise exceptions.SubprocessError(
56+
check_call(
57+
[PSPP_CONVERT_BIN, fp.name, csv_file.name],
58+
timeout=PSPP_CONVERT_TIMEOUT,
59+
)
60+
except CalledProcessError as err:
61+
raise SubprocessError(
5862
'Unable to convert the SPSS file to CSV, please try again later.',
59-
code=500,
63+
code=HTTPStatus.INTERNAL_SERVER_ERROR,
6064
process='pspp',
6165
cmd=str(err.cmd),
6266
returncode=err.returncode,
6367
path=fp.name,
6468
extension='sav',
6569
exporter_class='tabular',
6670
)
71+
except TimeoutExpired as err:
72+
# The return code 52 is not the error code returned by the
73+
# subprocess, but the error given to it by this waterbutler
74+
# processs, for timing out.
75+
raise SubprocessError(
76+
'CSV Conversion timed out.',
77+
code=HTTPStatus.GATEWAY_TIMEOUT,
78+
process='pspp',
79+
cmd=str(err.cmd),
80+
returncode=52,
81+
path=fp.name,
82+
extension='sav',
83+
exporter_class='tabular'
84+
)
6785
return csv_file

mfr/extensions/unoconv/export.py

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,37 @@
1-
import os
2-
import subprocess
1+
from http import HTTPStatus
2+
from os.path import basename, splitext
3+
from subprocess import run, CalledProcessError
34

4-
from mfr.core import extension
5-
from mfr.core import exceptions
5+
from mfr.core.extension import BaseExporter
6+
from mfr.core.exceptions import SubprocessError
7+
from mfr.extensions.unoconv.settings import (PORT,
8+
ADDRESS,
9+
UNOCONV_BIN,
10+
UNOCONV_TIMEOUT)
611

7-
from mfr.extensions.unoconv import settings
812

9-
10-
class UnoconvExporter(extension.BaseExporter):
13+
class UnoconvExporter(BaseExporter):
1114

1215
def export(self):
1316
try:
14-
subprocess.run([
15-
settings.UNOCONV_BIN,
17+
run([
18+
UNOCONV_BIN,
1619
'-n',
17-
'-c', 'socket,host={},port={};urp;StarOffice.ComponentContext'.format(settings.ADDRESS, settings.PORT),
20+
'-c', 'socket,host={},port={};urp;StarOffice.ComponentContext'.format(ADDRESS, PORT),
1821
'-f', self.format,
1922
'-o', self.output_file_path,
2023
'-vvv',
2124
self.source_file_path
22-
], check=True, timeout=settings.UNOCONV_TIMEOUT)
23-
24-
except subprocess.CalledProcessError as err:
25-
name, extension = os.path.splitext(os.path.split(self.source_file_path)[-1])
26-
raise exceptions.SubprocessError(
25+
], check=True, timeout=UNOCONV_TIMEOUT)
26+
except CalledProcessError as err:
27+
name, extension = splitext(basename(self.source_file_path))
28+
raise SubprocessError(
2729
'Unable to export the file in the requested format, please try again later.',
2830
process='unoconv',
2931
cmd=str(err.cmd),
3032
returncode=err.returncode,
3133
path=str(self.source_file_path),
32-
code=400,
34+
code=HTTPStatus.BAD_REQUEST,
3335
extension=extension or '',
3436
exporter_class='unoconv',
3537
)

0 commit comments

Comments
 (0)