Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use safe version of os.path.isfile #986

Merged
merged 3 commits into from
Jan 22, 2020
Merged
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
7 changes: 3 additions & 4 deletions panel/io/save.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,9 @@ def save(panel, filename, title=None, resources=None, template=None,
"""
from ..pane import PaneBase

if isinstance(panel, PaneBase):
if len(panel.layout) >= 1:
panel = panel.layout

if isinstance(panel, PaneBase) and len(panel.layout) > 1:
panel = panel.layout

doc = Document()
comm = Comm()
with config.set(embed=embed):
Expand Down
10 changes: 8 additions & 2 deletions panel/pane/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,10 @@ def get_pane_type(cls, obj, **kwargs):
for p in param.concrete_descendents(PaneBase).values():
if p.priority is None:
applies = True
priority = p.applies(obj, **(kwargs if p._applies_kw else {}))
try:
priority = p.applies(obj, **(kwargs if p._applies_kw else {}))
except:
priority = False
else:
applies = None
priority = p.priority
Expand All @@ -289,7 +292,10 @@ def get_pane_type(cls, obj, **kwargs):
pane_types = reversed(sorted(descendents, key=lambda x: x[0]))
for _, applies, pane_type in pane_types:
if applies is None:
applies = pane_type.applies(obj, **(kwargs if pane_type._applies_kw else {}))
try:
applies = pane_type.applies(obj, **(kwargs if pane_type._applies_kw else {}))
except:
applies = False
if not applies:
continue
return pane_type
Expand Down
20 changes: 5 additions & 15 deletions panel/pane/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
from __future__ import absolute_import, division, unicode_literals

import base64
import os

from io import BytesIO
from six import string_types

import param

from .markup import escape, DivPaneBase
from ..util import isfile, isurl


class ImageBase(DivPaneBase):
Expand Down Expand Up @@ -42,24 +42,14 @@ def applies(cls, obj):
if hasattr(obj, '_repr_{}_'.format(imgtype)):
return True
if isinstance(obj, string_types):
if os.path.isfile(obj) and obj.endswith('.'+imgtype):
if isfile(obj) and obj.endswith('.'+imgtype):
return True
if cls._is_url(obj):
if isurl(obj, [cls.imgtype]):
return True
if hasattr(obj, 'read'): # Check for file like object
return True
return False

@classmethod
def _is_url(cls, obj):
if isinstance(obj, string_types):
lower_string = obj.lower()
return (
lower_string.startswith('http://')
or lower_string.startswith('https://')
) and lower_string.endswith('.'+cls.imgtype)
return False

def _type_error(self, object):
if isinstance(object, string_types):
raise ValueError("%s pane cannot parse string that is not a filename "
Expand All @@ -70,12 +60,12 @@ def _img(self):
if hasattr(self.object, '_repr_{}_'.format(self.imgtype)):
return getattr(self.object, '_repr_' + self.imgtype + '_')()
if isinstance(self.object, string_types):
if os.path.isfile(self.object):
if isfile(self.object):
with open(self.object, 'rb') as f:
return f.read()
if hasattr(self.object, 'read'):
return self.object.read()
if self._is_url(self.object):
if isurl(self.object, [self.imgtype]):
import requests
r = requests.request(url=self.object, method='GET')
return r.content
Expand Down
15 changes: 3 additions & 12 deletions panel/pane/media.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import param

from ..models import Audio as _BkAudio, Video as _BkVideo
from ..util import isfile, isurl
from .base import PaneBase


Expand Down Expand Up @@ -51,24 +52,14 @@ class _MediaBase(PaneBase):
@classmethod
def applies(cls, obj):
if isinstance(obj, string_types):
if os.path.isfile(obj) and any(obj.endswith('.'+fmt) for fmt in cls._formats):
if isfile(obj) and any(obj.endswith('.'+fmt) for fmt in cls._formats):
return True
if cls._is_url(obj):
if isurl(obj, cls._formats):
return True
if hasattr(obj, 'read'): # Check for file like object
return True
return False

@classmethod
def _is_url(cls, obj):
if isinstance(obj, string_types):
lower_string = obj.lower()
return (
lower_string.startswith('http://')
or lower_string.startswith('https://')
) and any(lower_string.endswith('.'+fmt) for fmt in cls._formats)
return False

def _init_properties(self):
return {k: v for k, v in self.param.get_param_values()
if v is not None and k not in ['default_layout']}
Expand Down
4 changes: 2 additions & 2 deletions panel/pane/vtk/vtk.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from __future__ import absolute_import, division, unicode_literals

import sys
import os
import base64

try:
Expand All @@ -21,6 +20,7 @@
from pyviz_comms import JupyterComm

from ..base import PaneBase
from ...util import isfile

if sys.version_info >= (2, 7):
base64encode = lambda x: base64.b64encode(x).decode('utf-8')
Expand Down Expand Up @@ -292,7 +292,7 @@ def register_serializer(cls, class_type, serializer):
def _get_vtkjs(self):
if self._vtkjs is None and self.object is not None:
if isinstance(self.object, string_types) and self.object.endswith('.vtkjs'):
if os.path.isfile(self.object):
if isfile(self.object):
with open(self.object, 'rb') as f:
vtkjs = f.read()
else:
Expand Down
26 changes: 22 additions & 4 deletions panel/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
"""
from __future__ import absolute_import, division, unicode_literals

import re
import sys
import datetime as dt
import inspect
import numbers
import datetime as dt

import os
import re
import sys

from collections import defaultdict, OrderedDict
from datetime import datetime
Expand All @@ -33,6 +33,24 @@
unicode = str


def isfile(path):
"""Safe version of os.path.isfile robust to path length issues on Windows"""
try:
return os.path.isfile(path)
except ValueError: # path too long for Windows
return False


def isurl(obj, formats):
if not isinstance(obj, string_types):
return False
lower_string = obj.lower()
return (
lower_string.startswith('http://')
or lower_string.startswith('https://')
) and any(lower_string.endswith('.'+fmt) for fmt in formats)


def hashable(x):
if isinstance(x, MutableSequence):
return tuple(x)
Expand Down