Skip to content

Commit b1ffec1

Browse files
committed
use firefox headless
1 parent a61365c commit b1ffec1

File tree

4 files changed

+45
-26
lines changed

4 files changed

+45
-26
lines changed

.github/CONTRIBUTING.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ First of all, thanks for your interest in contributing!
6060
4. Make change to your local copy of the folium repository
6161
5. Make sure the tests pass:
6262
* in the repository folder do `pip install -e .` (needed for notebook tests)
63-
* along with all the dependencies install `phantomjs` via `npm install -g phantomjs` or by downloading it from [here](http://phantomjs.org/download.html) and installing manually
6463
* run `python -m pytest tests`
6564
* resolve all errors
6665
6. Commit those changes

.travis.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ language: minimal
22

33
sudo: false
44

5+
env:
6+
- MOZ_HEADLESS=1
7+
8+
addons:
9+
firefox: latest
10+
511
env:
612
global:
713
- secure: "gRT413onDOvwgiHpNXRsiqo+ZZSjwwBpjZryQ9h6IqYw6cTN9YVivYF15uTMD//mZyFeHRz+F/7/0EG2z+UYIBKbgktiNMbie/KizwRBnCThGpcch1VeizkBkPluWSQXndXM6STkHvn0eZBZBBh0QdTm1qaI0babUmgZuWhrX38="
@@ -31,8 +37,13 @@ before_install:
3137
- conda update conda
3238
- conda config --remove channels defaults --force
3339
- conda config --add channels conda-forge --force
34-
- conda create --name TEST python=$PY phantomjs --file requirements.txt --file requirements-dev.txt
40+
- conda create --name TEST python=$PY --file requirements.txt --file requirements-dev.txt
3541
- source activate TEST
42+
# firefox headless driver
43+
- wget https://github.com/mozilla/geckodriver/releases/download/v0.23.0/geckodriver-v0.23.0-linux64.tar.gz -O geckodriver.tar.gz
44+
- mkdir geckodriver
45+
- tar -xzf geckodriver.tar.gz -C geckodriver
46+
- export PATH=$PATH:$PWD/geckodriver
3647

3748
- if [[ "$PY" == "2.7" ]]; then
3849
conda install mock ;

folium/folium.py

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
from __future__ import (absolute_import, division, print_function)
99

10-
import os
1110
import time
1211
import warnings
1312

@@ -16,7 +15,7 @@
1615

1716
from folium.map import FitBounds
1817
from folium.raster_layers import TileLayer
19-
from folium.utilities import _validate_location
18+
from folium.utilities import _tmp_html, _validate_location
2019

2120
from jinja2 import Environment, PackageLoader, Template
2221

@@ -203,10 +202,10 @@ class Map(MacroElement):
203202
zoomControl: {{this.zoom_control.__str__().lower()}},
204203
});
205204
{% if this.control_scale %}L.control.scale().addTo({{this.get_name()}});{% endif %}
206-
205+
207206
{% if this.objects_to_stay_in_front %}
208207
function objects_in_front() {
209-
{% for obj in this.objects_to_stay_in_front %}
208+
{% for obj in this.objects_to_stay_in_front %}
210209
{{ obj.get_name() }}.bringToFront();
211210
{% endfor %}
212211
};
@@ -291,35 +290,30 @@ def _repr_html_(self, **kwargs):
291290
def _to_png(self, delay=3):
292291
"""Export the HTML to byte representation of a PNG image.
293292
294-
Uses Phantom JS to render the HTML and record a PNG. You may need to
293+
Uses selenium to render the HTML and record a PNG. You may need to
295294
adjust the `delay` time keyword argument if maps render without data or tiles.
296295
297296
Examples
298297
--------
299298
>>> map._to_png()
300299
>>> map._to_png(time=10) # Wait 10 seconds between render and snapshot.
301-
"""
302300
301+
"""
303302
if self._png_image is None:
304-
import selenium.webdriver
303+
from selenium import webdriver
304+
305+
options = webdriver.firefox.options.Options()
306+
options.add_argument('--headless')
307+
driver = webdriver.Firefox(options=options)
305308

306-
driver = selenium.webdriver.PhantomJS(
307-
service_log_path=os.path.devnull
308-
)
309-
driver.get('about:blank')
310309
html = self.get_root().render()
311-
html = html.replace('\'', '"').replace('"', '\\"')
312-
html = html.replace('\n', '')
313-
driver.execute_script('document.write(\"{}\")'.format(html))
314-
driver.maximize_window()
315-
# Ignore user map size.
316-
# todo: fix this
317-
# driver.execute_script("document.body.style.width = '100%';") # noqa
318-
# We should probably monitor if some element is present,
319-
# but this is OK for now.
320-
time.sleep(delay)
321-
png = driver.get_screenshot_as_png()
322-
driver.quit()
310+
with _tmp_html(html) as tmp:
311+
# We need the tempfile to avoid JS security issues.
312+
driver.get('file:///{path}'.format(path=tmp.name))
313+
driver.maximize_window()
314+
time.sleep(delay)
315+
png = driver.get_screenshot_as_png()
316+
driver.quit()
323317
self._png_image = png
324318
return self._png_image
325319

folium/utilities.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import os
88
import struct
99
import zlib
10+
from contextlib import contextmanager
11+
from tempfile import NamedTemporaryFile
1012

1113
import numpy as np
1214

@@ -112,7 +114,7 @@ def _is_url(url):
112114
"""Check to see if `url` has a valid protocol."""
113115
try:
114116
return urlparse(url).scheme in _VALID_URLS
115-
except:
117+
except Exception:
116118
return False
117119

118120

@@ -356,3 +358,16 @@ def camelize(key):
356358
"""
357359
return ''.join(x.capitalize() if i > 0 else x
358360
for i, x in enumerate(key.split('_')))
361+
362+
363+
@contextmanager
364+
def _tmp_html(data):
365+
tmp = None
366+
try:
367+
tmp = NamedTemporaryFile(suffix='.html', prefix='folium_')
368+
tmp.write(data.encode('utf8'))
369+
tmp.flush()
370+
yield tmp
371+
finally:
372+
if tmp is not None:
373+
tmp.close()

0 commit comments

Comments
 (0)