Skip to content

Commit

Permalink
Add fsdecode as a wrapper for os.fsdecode and clean filename handling
Browse files Browse the repository at this point in the history
os.fsdecode was introduced in python 3.2, so I implemented fsdecode in
utils.py to be able to use it on previous versions. fsdecode thus
returns the filename passed as parameter as a unicode string (either
if it's str or bytes), and if a PathLike object is used, it returns
its filename. In other case, it raises a TypeError exception.

Changed code in from_file and mediainfo_json to use it, which simplifies
the code a bit and hopefully fixes the last windows appveyor error.
  • Loading branch information
antlarr committed Apr 17, 2018
1 parent d7879a7 commit 149a81f
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 24 deletions.
32 changes: 12 additions & 20 deletions pydub/audio_segment.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import sys
import struct
from .logging_utils import log_conversion, log_subprocess_output
from .utils import mediainfo_json
from .utils import mediainfo_json, fsdecode
import base64
from collections import namedtuple

Expand Down Expand Up @@ -492,13 +492,7 @@ def from_mono_audiosegments(cls, *mono_segments):

@classmethod
def from_file_using_temporary_files(cls, file, format=None, codec=None, parameters=None, **kwargs):
try:
if isinstance(file, os.PathLike):
orig_file = os.fspath(file)
else:
orig_file = file
except AttributeError:
orig_file = file
orig_file = file
file = _fd_or_path_or_tempfile(file, 'rb', tempfile=False)

if format:
Expand Down Expand Up @@ -595,13 +589,11 @@ def is_format(f):

@classmethod
def from_file(cls, file, format=None, codec=None, parameters=None, **kwargs):
orig_file = file
try:
if isinstance(file, os.PathLike):
orig_file = os.fspath(file)
else:
orig_file = file
except AttributeError:
orig_file = file
filename = fsdecode(file)
except TypeError:
filename = None
file = _fd_or_path_or_tempfile(file, 'rb', tempfile=False)

if format:
Expand All @@ -612,10 +604,10 @@ def is_format(f):
f = f.lower()
if format == f:
return True
if isinstance(orig_file, basestring):
return orig_file.lower().endswith(".{0}".format(f))
if isinstance(orig_file, bytes):
return orig_file.lower().endswith((".{0}".format(f)).encode('utf8'))

if filename:
return filename.lower().endswith(".{0}".format(f))

return False

if is_format("wav"):
Expand Down Expand Up @@ -648,8 +640,8 @@ def is_format(f):
# force audio decoder
conversion_command += ["-acodec", codec]

if isinstance(orig_file, (basestring, bytes)):
conversion_command += ["-i", orig_file]
if filename:
conversion_command += ["-i", filename]
stdin_parameter = None
stdin_data = None
else:
Expand Down
25 changes: 21 additions & 4 deletions pydub/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,21 +202,38 @@ def get_prober_name():
return "ffprobe"


def fsdecode(filename):
"""Wrapper for os.fsdecode which was introduced in python 3.2 ."""

if sys.version_info >= (3, 2):
PathLikeTypes = (basestring, bytes)
if sys.version_info >= (3, 6):
PathLikeTypes += (os.PathLike,)
if isinstance(filename, PathLikeTypes):
return os.fsdecode(filename)
else:
if isinstance(filename, bytes):
return filename.decode(sys.getfilesystemencoding())
if isinstance(filename, basestring):
return filename

raise TypeError("type {0} not accepted by fsdecode".format(type(filename)))


def mediainfo_json(filepath):
"""Return json dictionary with media info(codec, duration, size, bitrate...) from filepath
"""

prober = get_prober_name()
command_args = [
"-v", "info",
"-show_format",
"-show_streams",
]
if isinstance(filepath, (basestring, bytes)):
command_args += [filepath]
try:
command_args += [fsdecode(filepath)]
stdin_parameter = None
stdin_data = None
else:
except TypeError:
command_args += ["-"]
stdin_parameter = PIPE
file = _fd_or_path_or_tempfile(filepath, 'rb', tempfile=False)
Expand Down

0 comments on commit 149a81f

Please sign in to comment.