Convert between str-unicode on app bounds, fixes #57
parent
a254ed99ac
commit
638d4e70ed
|
@ -17,7 +17,6 @@ Example:
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os.path
|
|
||||||
import gettext
|
import gettext
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -37,7 +37,10 @@ from .parsers import OptionsParser
|
||||||
from .updatemanager import UpdateThread
|
from .updatemanager import UpdateThread
|
||||||
from .downloaders import YoutubeDLDownloader
|
from .downloaders import YoutubeDLDownloader
|
||||||
|
|
||||||
from .utils import YOUTUBEDL_BIN
|
from .utils import (
|
||||||
|
YOUTUBEDL_BIN,
|
||||||
|
os_path_exists
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
MANAGER_PUB_TOPIC = 'dlmanager'
|
MANAGER_PUB_TOPIC = 'dlmanager'
|
||||||
|
@ -201,7 +204,7 @@ class DownloadManager(Thread):
|
||||||
|
|
||||||
def _check_youtubedl(self):
|
def _check_youtubedl(self):
|
||||||
"""Check if youtube-dl binary exists. If not try to download it. """
|
"""Check if youtube-dl binary exists. If not try to download it. """
|
||||||
if not os.path.exists(self._youtubedl_path()):
|
if not os_path_exists(self._youtubedl_path()):
|
||||||
UpdateThread(self.opt_manager.options['youtubedl_path'], True).join()
|
UpdateThread(self.opt_manager.options['youtubedl_path'], True).join()
|
||||||
|
|
||||||
def _jobs_done(self):
|
def _jobs_done(self):
|
||||||
|
|
|
@ -9,6 +9,7 @@ import os.path
|
||||||
from time import strftime
|
from time import strftime
|
||||||
|
|
||||||
from .utils import (
|
from .utils import (
|
||||||
|
os_path_exists,
|
||||||
get_encoding,
|
get_encoding,
|
||||||
check_path
|
check_path
|
||||||
)
|
)
|
||||||
|
@ -35,7 +36,7 @@ class LogManager(object):
|
||||||
|
|
||||||
LOG_FILENAME = "log"
|
LOG_FILENAME = "log"
|
||||||
TIME_TEMPLATE = "[{time}] {error_msg}"
|
TIME_TEMPLATE = "[{time}] {error_msg}"
|
||||||
MAX_LOGSIZE = 524288
|
MAX_LOGSIZE = 524288 # Bytes
|
||||||
|
|
||||||
def __init__(self, config_path, add_time=False):
|
def __init__(self, config_path, add_time=False):
|
||||||
self.config_path = config_path
|
self.config_path = config_path
|
||||||
|
@ -47,7 +48,7 @@ class LogManager(object):
|
||||||
|
|
||||||
def log_size(self):
|
def log_size(self):
|
||||||
"""Return log file size in Bytes. """
|
"""Return log file size in Bytes. """
|
||||||
if not os.path.exists(self.log_file):
|
if not os_path_exists(self.log_file):
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
return os.path.getsize(self.log_file)
|
return os.path.getsize(self.log_file)
|
||||||
|
@ -88,7 +89,7 @@ class LogManager(object):
|
||||||
|
|
||||||
def _init_log(self):
|
def _init_log(self):
|
||||||
"""Initialize the log file if not exist. """
|
"""Initialize the log file if not exist. """
|
||||||
if not os.path.exists(self.log_file):
|
if not os_path_exists(self.log_file):
|
||||||
self._write('', 'w')
|
self._write('', 'w')
|
||||||
|
|
||||||
def _auto_clear_log(self):
|
def _auto_clear_log(self):
|
||||||
|
|
|
@ -20,7 +20,10 @@ from .info import (
|
||||||
__author__
|
__author__
|
||||||
)
|
)
|
||||||
|
|
||||||
from .utils import TwoWayOrderedDict as twodict
|
from .utils import (
|
||||||
|
TwoWayOrderedDict as twodict,
|
||||||
|
os_path_exists
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class OptionsFrame(wx.Frame):
|
class OptionsFrame(wx.Frame):
|
||||||
|
@ -1493,5 +1496,5 @@ class LogGUI(wx.Frame):
|
||||||
|
|
||||||
def load(self, filename):
|
def load(self, filename):
|
||||||
"""Load file content on the text area. """
|
"""Load file content on the text area. """
|
||||||
if os.path.exists(filename):
|
if os_path_exists(filename):
|
||||||
self._text_area.LoadFile(filename)
|
self._text_area.LoadFile(filename)
|
||||||
|
|
|
@ -9,6 +9,8 @@ import json
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
from .utils import (
|
from .utils import (
|
||||||
|
os_path_expanduser,
|
||||||
|
os_path_exists,
|
||||||
encode_tuple,
|
encode_tuple,
|
||||||
decode_tuple,
|
decode_tuple,
|
||||||
check_path
|
check_path
|
||||||
|
@ -198,7 +200,7 @@ class OptionsManager(object):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.options = {
|
self.options = {
|
||||||
'save_path': os.path.expanduser('~'),
|
'save_path': os_path_expanduser('~'),
|
||||||
'video_format': '0',
|
'video_format': '0',
|
||||||
'second_video_format': '0',
|
'second_video_format': '0',
|
||||||
'to_audio': False,
|
'to_audio': False,
|
||||||
|
@ -246,7 +248,7 @@ class OptionsManager(object):
|
||||||
|
|
||||||
def load_from_file(self):
|
def load_from_file(self):
|
||||||
"""Load options from settings file. """
|
"""Load options from settings file. """
|
||||||
if not os.path.exists(self.settings_file):
|
if not os_path_exists(self.settings_file):
|
||||||
return
|
return
|
||||||
|
|
||||||
with open(self.settings_file, 'rb') as settings_file:
|
with open(self.settings_file, 'rb') as settings_file:
|
||||||
|
|
|
@ -29,21 +29,91 @@ if os.name == 'nt':
|
||||||
YOUTUBEDL_BIN += '.exe'
|
YOUTUBEDL_BIN += '.exe'
|
||||||
|
|
||||||
|
|
||||||
|
def get_encoding():
|
||||||
|
"""Return system encoding. """
|
||||||
|
try:
|
||||||
|
encoding = locale.getpreferredencoding()
|
||||||
|
'TEST'.encode(encoding)
|
||||||
|
except:
|
||||||
|
encoding = 'UTF-8'
|
||||||
|
|
||||||
|
return encoding
|
||||||
|
|
||||||
|
|
||||||
|
def convert_on_bounds(func):
|
||||||
|
"""Decorator to convert string inputs & outputs.
|
||||||
|
|
||||||
|
Covert string inputs & outputs between 'str' and 'unicode' at the
|
||||||
|
application bounds using the preferred system encoding. It will convert
|
||||||
|
all the string params (args, kwargs) to 'str' type and all the
|
||||||
|
returned strings values back to 'unicode'.
|
||||||
|
|
||||||
|
"""
|
||||||
|
def convert_item(item, to_unicode=False):
|
||||||
|
"""The actual function which handles the conversion.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
item (-): Can be any python item.
|
||||||
|
|
||||||
|
to_unicode (boolean): When True it will convert all the 'str' types
|
||||||
|
to 'unicode'. When False it will convert all the 'unicode'
|
||||||
|
types back to 'str'.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if to_unicode and isinstance(item, str):
|
||||||
|
# Convert str to unicode
|
||||||
|
return item.decode(get_encoding(), 'ignore')
|
||||||
|
|
||||||
|
if not to_unicode and isinstance(item, unicode):
|
||||||
|
# Convert unicode to str
|
||||||
|
return item.encode(get_encoding(), 'ignore')
|
||||||
|
|
||||||
|
if hasattr(item, '__iter__'):
|
||||||
|
# Handle iterables
|
||||||
|
temp_list = []
|
||||||
|
|
||||||
|
for sub_item in item:
|
||||||
|
if isinstance(item, dict):
|
||||||
|
temp_list.append((sub_item, covert_item(item[sub_item])))
|
||||||
|
else:
|
||||||
|
temp_list.append(convert_item(sub_item))
|
||||||
|
|
||||||
|
return type(item)(temp_list)
|
||||||
|
|
||||||
|
return item
|
||||||
|
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
returned_value = func(*convert_item(args), **convert_item(kwargs))
|
||||||
|
|
||||||
|
return convert_item(returned_value, True)
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
# See: https://github.com/MrS0m30n3/youtube-dl-gui/issues/57
|
||||||
|
# Patch os functions to convert between 'str' and 'unicode' on app bounds
|
||||||
|
os_getenv = convert_on_bounds(os.getenv)
|
||||||
|
os_makedirs = convert_on_bounds(os.makedirs)
|
||||||
|
os_path_isdir = convert_on_bounds(os.path.isdir)
|
||||||
|
os_path_exists = convert_on_bounds(os.path.exists)
|
||||||
|
os_path_dirname = convert_on_bounds(os.path.dirname)
|
||||||
|
os_path_abspath = convert_on_bounds(os.path.abspath)
|
||||||
|
os_path_realpath = convert_on_bounds(os.path.realpath)
|
||||||
|
os_path_expanduser = convert_on_bounds(os.path.expanduser)
|
||||||
|
|
||||||
|
# Patch Windows specific functions
|
||||||
|
if os.name == 'nt':
|
||||||
|
os_startfile = convert_on_bounds(os.startfile)
|
||||||
|
|
||||||
|
|
||||||
def remove_shortcuts(path):
|
def remove_shortcuts(path):
|
||||||
"""Return given path after removing the shortcuts. """
|
"""Return given path after removing the shortcuts. """
|
||||||
path = path.replace('~', os.path.expanduser('~'))
|
return path.replace('~', os_path_expanduser('~'))
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def absolute_path(filename):
|
def absolute_path(filename):
|
||||||
"""Return absolute path to the given file. """
|
"""Return absolute path to the given file. """
|
||||||
path = os.path.realpath(os.path.abspath(filename))
|
return os_path_dirname(os_path_realpath(os_path_abspath(filename)))
|
||||||
return os.path.dirname(path).decode(get_encoding(), 'ignore')
|
|
||||||
|
|
||||||
|
|
||||||
def get_lib_path():
|
|
||||||
"""Return path to the current file. """
|
|
||||||
return os.path.dirname(__file__).decode(get_encoding(), 'ignore')
|
|
||||||
|
|
||||||
|
|
||||||
def open_dir(path):
|
def open_dir(path):
|
||||||
|
@ -51,11 +121,11 @@ def open_dir(path):
|
||||||
Return True if path exists else False. """
|
Return True if path exists else False. """
|
||||||
path = remove_shortcuts(path)
|
path = remove_shortcuts(path)
|
||||||
|
|
||||||
if not os.path.exists(path):
|
if not os_path_exists(path):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
os.startfile(path)
|
os_startfile(path)
|
||||||
else:
|
else:
|
||||||
subprocess.call(('xdg-open', path))
|
subprocess.call(('xdg-open', path))
|
||||||
|
|
||||||
|
@ -66,6 +136,7 @@ def encode_tuple(tuple_to_encode):
|
||||||
"""Turn size tuple into string. """
|
"""Turn size tuple into string. """
|
||||||
return '%s/%s' % (tuple_to_encode[0], tuple_to_encode[1])
|
return '%s/%s' % (tuple_to_encode[0], tuple_to_encode[1])
|
||||||
|
|
||||||
|
|
||||||
def decode_tuple(encoded_tuple):
|
def decode_tuple(encoded_tuple):
|
||||||
"""Turn tuple string back to tuple. """
|
"""Turn tuple string back to tuple. """
|
||||||
s = encoded_tuple.split('/')
|
s = encoded_tuple.split('/')
|
||||||
|
@ -74,8 +145,8 @@ def decode_tuple(encoded_tuple):
|
||||||
|
|
||||||
def check_path(path):
|
def check_path(path):
|
||||||
"""Create path if not exist. """
|
"""Create path if not exist. """
|
||||||
if not os.path.exists(path):
|
if not os_path_exists(path):
|
||||||
os.makedirs(path)
|
os_makedirs(path)
|
||||||
|
|
||||||
|
|
||||||
def get_config_path():
|
def get_config_path():
|
||||||
|
@ -87,9 +158,9 @@ def get_config_path():
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
path = os.getenv('APPDATA')
|
path = os_getenv('APPDATA')
|
||||||
else:
|
else:
|
||||||
path = os.path.join(os.path.expanduser('~'), '.config')
|
path = os.path.join(os_path_expanduser('~'), '.config')
|
||||||
|
|
||||||
return os.path.join(path, __appname__.lower())
|
return os.path.join(path, __appname__.lower())
|
||||||
|
|
||||||
|
@ -164,17 +235,6 @@ def get_time(seconds):
|
||||||
return dtime
|
return dtime
|
||||||
|
|
||||||
|
|
||||||
def get_encoding():
|
|
||||||
"""Return system encoding. """
|
|
||||||
try:
|
|
||||||
encoding = locale.getpreferredencoding()
|
|
||||||
'TEST'.encode(encoding)
|
|
||||||
except:
|
|
||||||
encoding = 'UTF-8'
|
|
||||||
|
|
||||||
return encoding
|
|
||||||
|
|
||||||
|
|
||||||
def get_locale_file():
|
def get_locale_file():
|
||||||
"""Search for youtube-dlg locale file.
|
"""Search for youtube-dlg locale file.
|
||||||
|
|
||||||
|
@ -191,7 +251,7 @@ def get_locale_file():
|
||||||
|
|
||||||
SEARCH_DIRS = [
|
SEARCH_DIRS = [
|
||||||
os.path.join(absolute_path(sys.argv[0]), DIR_NAME),
|
os.path.join(absolute_path(sys.argv[0]), DIR_NAME),
|
||||||
os.path.join(get_lib_path(), DIR_NAME),
|
os.path.join(os_path_dirname(__file__), DIR_NAME),
|
||||||
os.path.join('/usr', 'share', __appname__.lower(), DIR_NAME)
|
os.path.join('/usr', 'share', __appname__.lower(), DIR_NAME)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -199,7 +259,7 @@ def get_locale_file():
|
||||||
SEARCH_DIRS.append('/usr/local/Cellar/youtube-dl-gui/{version}/share/locale'.format(version=__version__))
|
SEARCH_DIRS.append('/usr/local/Cellar/youtube-dl-gui/{version}/share/locale'.format(version=__version__))
|
||||||
|
|
||||||
for directory in SEARCH_DIRS:
|
for directory in SEARCH_DIRS:
|
||||||
if os.path.isdir(directory):
|
if os_path_isdir(directory):
|
||||||
return directory
|
return directory
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
@ -224,11 +284,11 @@ def get_icon_file():
|
||||||
|
|
||||||
search_dirs = [
|
search_dirs = [
|
||||||
os.path.join(absolute_path(sys.argv[0]), 'icons'),
|
os.path.join(absolute_path(sys.argv[0]), 'icons'),
|
||||||
os.path.join(get_lib_path(), 'icons'),
|
os.path.join(os_path_dirname(__file__), 'icons'),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Append $XDG_DATA_DIRS on search_dirs
|
# Append $XDG_DATA_DIRS on search_dirs
|
||||||
path = os.getenv('XDG_DATA_DIRS')
|
path = os_getenv('XDG_DATA_DIRS')
|
||||||
|
|
||||||
if path is not None:
|
if path is not None:
|
||||||
for xdg_path in path.split(':'):
|
for xdg_path in path.split(':'):
|
||||||
|
@ -244,7 +304,7 @@ def get_icon_file():
|
||||||
for icon in ICONS_LIST:
|
for icon in ICONS_LIST:
|
||||||
icon_file = os.path.join(directory, icon)
|
icon_file = os.path.join(directory, icon)
|
||||||
|
|
||||||
if os.path.exists(icon_file):
|
if os_path_exists(icon_file):
|
||||||
return icon_file
|
return icon_file
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
Loading…
Reference in New Issue