Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
environment:

matrix:
# For Python versions available on Appveyor, see
# http://www.appveyor.com/docs/installed-software#python
- PYTHON: "C:\\Python36-x64"
PYTHON_VERSION: "3.6"
PYTHON_ARCH: "64"

init:
- "ECHO %PYTHON% %PYTHON_VERSION% %PYTHON_ARCH%"

# Add Python binaries to the path
- "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
- "python --version"


install:
# Upgrade PIP and setuptools to allow installation of pre-compiled wheels instead of compiling by ourselves
- "python -m pip install --upgrade pip"
- "pip install --upgrade setuptools"

- "pip install -e .[test]"

build: off

test_script:
# Run test files via py.test and generate JUnit XML. Then push test results
# to appveyor. The plugin pytest-cov takes care of coverage.
- ps: |
& pytest -W ignore::DeprecationWarning --junitxml=.\unittests.xml pygal/test
$testsExitCode = $lastexitcode

# Upload test results to AppVeyor
$wc = New-Object 'System.Net.WebClient'
$wc.UploadFile("https://ci.appveyor.com/api/testresults/junit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path .\unittests.xml))

if ($testsExitCode -ne 0) {exit $testsExitCode}

artifacts:
- path: .\unittests.xml
38 changes: 36 additions & 2 deletions pygal/svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import io
import json
import os
import urllib
from datetime import date, datetime
from math import pi
from numbers import Number
Expand Down Expand Up @@ -84,6 +85,38 @@ def __init__(self, graph):
for def_ in self.graph.defs:
self.defs.append(etree.fromstring(def_))

def file_uri_to_file_path(self, file_uri):
"""
Convert file URI ("file://...") to file path without "file://" (in a simplest case).

On Windows, file uri "file:///c:/dir/file.ext" is converted to "c:/dir/file.ext".
On *nix, file uri "file:///dir/file.ext" is converted to "/dir/file.ext".
The escaped characters like "%20" (space) are unescaped.

Examples:

>>> Svg.file_uri_to_path('file:///home/user/file.ext')
'/home/user/file.ext'

>>> Svg.file_uri_to_path('file:///c:/temp/file.ext')
'c:/temp/file.ext'

>>> Svg.file_uri_to_path('file:///c:/Program%20Files/file.ext')
'c:/Program files/file.ext'
"""

if not file_uri.startswith('file://'):
raise ValueError("Invalid file uri {}: should start with 'file://'".format(file_uri))

file_path = urllib.parse.unquote(file_uri[len('file://'):])

# Remove leading "/" character if a Windows-like drive letter is present, like: "/c:/dir/..."
if len(file_path) > 3 and file_path[0] == '/' and file_path[2] == ':':
file_path = file_path[1:]

return file_path


def add_styles(self):
"""Add the css to the svg"""
colors = self.graph.style.get_colors(self.id, self.graph._order)
Expand All @@ -102,7 +135,8 @@ def add_styles(self):
if css.startswith('inline:'):
css_text = css[len('inline:'):]
elif css.startswith('file://'):
css = css[len('file://'):]
css = self.file_uri_to_file_path(css)


if not os.path.exists(css):
css = os.path.join(os.path.dirname(__file__), 'css', css)
Expand Down Expand Up @@ -168,7 +202,7 @@ def json_default(o):
for js in self.graph.js:
if js.startswith('file://'):
script = self.node(self.defs, 'script', type='text/javascript')
with io.open(js[len('file://'):], encoding='utf-8') as f:
with io.open(self.file_uri_to_file_path(js), encoding='utf-8') as f:
script.text = f.read()
else:
if js.startswith('//') and self.graph.force_uri_protocol:
Expand Down
18 changes: 13 additions & 5 deletions pygal/test/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
"""Various config options tested on one chart type or more"""

from tempfile import NamedTemporaryFile
import pathlib
import os

from pygal import (
XY, Bar, Box, Config, DateLine, DateTimeLine, Dot, Funnel, Gauge,
Expand Down Expand Up @@ -334,22 +336,28 @@ def test_include_x_axis(Chart):
def test_css(Chart):
"""Test css file option"""
css = "{{ id }}text { fill: #bedead; }\n"
with NamedTemporaryFile('w') as f:
f.write(css)
f.flush()

f = NamedTemporaryFile('w', suffix='.css', delete=False)
filename = f.name
f.write(css)
f.close() # close the file to avoid the permission issue on Window when opening it for reading below

try:
config = Config()
config.css.append('file://' + f.name)
print(f.name)
config.css.append(pathlib.Path(f.name).as_uri())

chart = Chart(config)
chart.add('/', [10, 1, 5])
svg = chart.render().decode('utf-8')
assert '#bedead' in svg

chart = Chart(css=(_ellipsis, 'file://' + f.name))
chart = Chart(css=(_ellipsis, pathlib.Path(f.name).as_uri()))
chart.add('/', [10, 1, 5])
svg = chart.render().decode('utf-8')
assert '#bedead' in svg
finally:
os.remove(filename)


def test_inline_css(Chart):
Expand Down
10 changes: 5 additions & 5 deletions pygal/test/test_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

try:
import cairosvg
except ImportError:
except (ImportError, OSError): # OSError is raised on Windows if cairo's DLLs are missing
cairosvg = None


Expand All @@ -45,9 +45,9 @@ def test_multi_render(Chart, datas):
assert svg == chart.render()


def test_render_to_file(Chart, datas):
def test_render_to_file(Chart, datas, tmpdir):
"""Test in file rendering"""
file_name = '/tmp/test_graph-%s.svg' % uuid.uuid4()
file_name = str(tmpdir.join('test_graph-%s.png' % uuid.uuid4()))
if os.path.exists(file_name):
os.remove(file_name)

Expand All @@ -60,9 +60,9 @@ def test_render_to_file(Chart, datas):


@pytest.mark.skipif(not cairosvg, reason="CairoSVG not installed")
def test_render_to_png(Chart, datas):
def test_render_to_png(Chart, datas, tmpdir):
"""Test in file png rendering"""
file_name = '/tmp/test_graph-%s.png' % uuid.uuid4()
file_name = str(tmpdir.join('test_graph-%s.png' % uuid.uuid4()))
if os.path.exists(file_name):
os.remove(file_name)

Expand Down