Skip to content

Commit cd9252f

Browse files
committed
Updates to resolve inconsistent Python2 string encoding/decoding
- What a mess
1 parent 994c667 commit cd9252f

10 files changed

Lines changed: 144 additions & 79 deletions

File tree

resources/lib/youtube_plugin/kodion/abstract_provider.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
SearchHistoryItem,
3939
UriItem,
4040
)
41-
from .utils.convert_format import to_unicode
4241

4342

4443
class AbstractProvider(object):
@@ -414,7 +413,7 @@ def on_search(provider, context, re_match):
414413
search_history = context.get_search_history()
415414

416415
if not command or command == 'query':
417-
query = to_unicode(params.get('q', ''))
416+
query = params.get('q', '')
418417
if query:
419418
result, options = provider.on_search_run(context, query=query)
420419
if not options:
@@ -430,7 +429,7 @@ def on_search(provider, context, re_match):
430429
context.set_path(PATHS.SEARCH, command)
431430

432431
if command == 'remove':
433-
query = to_unicode(params.get('q', ''))
432+
query = params.get('q', '')
434433
if not ui.on_yes_no_input(
435434
localize('content.remove'),
436435
localize('content.remove.check.x', query),
@@ -444,7 +443,7 @@ def on_search(provider, context, re_match):
444443
return True, {provider.FORCE_REFRESH: True}
445444

446445
if command == 'rename':
447-
query = to_unicode(params.get('q', ''))
446+
query = params.get('q', '')
448447
result, new_query = ui.on_keyboard_input(
449448
localize('search.rename'), query
450449
)

resources/lib/youtube_plugin/kodion/compatibility/__init__.py

Lines changed: 116 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66
SPDX-License-Identifier: GPL-2.0-only
77
See LICENSES/GPL-2.0-only for more information.
88
"""
9+
from __future__ import absolute_import, division, unicode_literals
10+
911

1012
__all__ = (
1113
'BaseHTTPRequestHandler',
1214
'StringIO',
1315
'TCPServer',
1416
'ThreadingMixIn',
1517
'available_cpu_count',
16-
'byte_string_type',
1718
'datetime_infolabel',
1819
'entity_escape',
1920
'generate_hash',
@@ -25,6 +26,7 @@
2526
'range_type',
2627
'string_type',
2728
'to_str',
29+
'to_unicode',
2830
'unescape',
2931
'unquote',
3032
'unquote_plus',
@@ -72,11 +74,16 @@
7274

7375
range_type = (range, list)
7476

75-
byte_string_type = bytes
7677
string_type = str
7778
to_str = str
7879

7980

81+
def to_unicode(text):
82+
if isinstance(text, bytes):
83+
text = text.decode('utf-8', errors='ignore')
84+
return text
85+
86+
8087
def entity_escape(text,
8188
entities=str.maketrans({
8289
'&': '&',
@@ -133,8 +140,8 @@ def generate_hash(*args, **kwargs):
133140
urlencode as _urlencode,
134141
)
135142
from urlparse import (
136-
parse_qs,
137-
parse_qsl,
143+
parse_qs as _parse_qs,
144+
parse_qsl as _parse_qsl,
138145
urljoin,
139146
urlsplit,
140147
urlunsplit,
@@ -150,38 +157,103 @@ def generate_hash(*args, **kwargs):
150157
)
151158

152159

153-
def quote(data, *args, **kwargs):
154-
return _quote(to_str(data), *args, **kwargs)
155-
156-
157-
def quote_plus(data, *args, **kwargs):
158-
return _quote_plus(to_str(data), *args, **kwargs)
159-
160-
161-
def unquote(data):
162-
return _unquote(to_str(data))
163-
164-
165-
def unquote_plus(data):
166-
return _unquote_plus(to_str(data))
167-
168-
169-
def urlencode(data, *args, **kwargs):
170-
if isinstance(data, dict):
171-
data = data.items()
172-
kwargs = {
173-
key: value
174-
for key, value in kwargs.viewitems()
175-
if key in {'query', 'doseq'}
176-
}
177-
return _urlencode({
178-
to_str(key): (
179-
[to_str(part) for part in value]
160+
def parse_qs(*args, **kwargs):
161+
num_args = len(args)
162+
query_dict = _parse_qs(
163+
to_str(args[0] if args else kwargs.get('qs')),
164+
keep_blank_values=(
165+
args[1]
166+
if num_args >= 2 else
167+
kwargs.get('keep_blank_values', 0)
168+
),
169+
strict_parsing=(
170+
args[2]
171+
if num_args >= 3 else
172+
kwargs.get('strict_parsing', 0)
173+
),
174+
# max_num_fields=(
175+
# args[3]
176+
# if num_args >= 4 else
177+
# kwargs.get('max_num_fields', 0)
178+
# ),
179+
)
180+
return {
181+
to_unicode(key): (
182+
[to_unicode(part) for part in value]
180183
if isinstance(value, (list, tuple)) else
181-
to_str(value)
184+
to_unicode(value)
182185
)
183-
for key, value in data
184-
}, *args, **kwargs)
186+
for key, value in query_dict.viewitems()
187+
}
188+
189+
190+
def parse_qsl(*args, **kwargs):
191+
num_args = len(args)
192+
query_list = _parse_qsl(
193+
to_str(args[0] if args else kwargs.get('qs')),
194+
keep_blank_values=(
195+
args[1]
196+
if num_args >= 2 else
197+
kwargs.get('keep_blank_values', 0)
198+
),
199+
strict_parsing=(
200+
args[2]
201+
if num_args >= 3 else
202+
kwargs.get('strict_parsing', 0)
203+
),
204+
# max_num_fields=(
205+
# args[3]
206+
# if num_args >= 4 else
207+
# kwargs.get('max_num_fields', 0)
208+
# ),
209+
)
210+
return [
211+
(to_unicode(key), to_unicode(value))
212+
for key, value in query_list
213+
]
214+
215+
216+
def quote(*args, **kwargs):
217+
return _quote(
218+
to_str(args[0] if args else kwargs.get('string')),
219+
safe=args[1] if len(args) >= 2 else kwargs.get('safe', '/'),
220+
)
221+
222+
223+
def quote_plus(*args, **kwargs):
224+
return _quote_plus(
225+
to_str(args[0] if args else kwargs.get('string')),
226+
safe=args[1] if len(args) >= 2 else kwargs.get('safe', '/'),
227+
)
228+
229+
230+
def unquote(*args, **kwargs):
231+
return _unquote(
232+
to_str(args[0] if args else kwargs.get('string'))
233+
)
234+
235+
236+
def unquote_plus(*args, **kwargs):
237+
return _unquote_plus(
238+
to_str(args[0] if args else kwargs.get('string'))
239+
)
240+
241+
242+
def urlencode(*args, **kwargs):
243+
query = args[0] if args else kwargs.get('query')
244+
if isinstance(query, dict):
245+
query = query.viewitems()
246+
return _urlencode(
247+
query={
248+
to_str(key): (
249+
[to_str(part) for part in value]
250+
if isinstance(value, (list, tuple)) else
251+
to_str(value)
252+
)
253+
for key, value in query
254+
},
255+
doseq=args[1] if len(args) >= 2 else kwargs.get('doseq', 0),
256+
)
185257

186258

187259
class StringIO(_StringIO):
@@ -205,18 +277,23 @@ def __exit__(self, exc_type, exc_val, exc_tb):
205277

206278
range_type = (xrange, list)
207279

208-
byte_string_type = (bytes, str)
209280
string_type = basestring
210281

211282

212-
def to_str(value, _format='{0!s}'.format):
283+
def to_str(value, _format=b'{0!s}'.format):
213284
if not isinstance(value, basestring):
214285
value = _format(value)
215-
if isinstance(value, unicode):
216-
value = value.encode('utf-8')
286+
elif isinstance(value, unicode):
287+
value = value.encode('utf-8', errors='ignore')
217288
return value
218289

219290

291+
def to_unicode(text):
292+
if isinstance(text, (bytes, str)):
293+
text = text.decode('utf-8', errors='ignore')
294+
return text
295+
296+
220297
def entity_escape(text,
221298
entities={
222299
'&': '&',
@@ -231,7 +308,7 @@ def entity_escape(text,
231308

232309

233310
def generate_hash(*args, **kwargs):
234-
return md5(''.join(
311+
return md5(b''.join(
235312
map(to_str, args or kwargs.get('iter'))
236313
)).hexdigest()
237314

resources/lib/youtube_plugin/kodion/context/xbmc/xbmc_context.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
from ...player import XbmcPlaylistPlayer
4848
from ...settings import XbmcPluginSettings
4949
from ...ui import XbmcContextUI
50-
from ...utils.convert_format import to_unicode
5150
from ...utils.file_system import make_dirs
5251
from ...utils.methods import (
5352
get_kodi_setting_bool,
@@ -470,7 +469,7 @@ def __init__(self,
470469
def init(self):
471470
num_args = len(sys.argv)
472471
if num_args:
473-
uri = to_unicode(sys.argv[0])
472+
uri = sys.argv[0]
474473
if uri.startswith('plugin://'):
475474
self._plugin_handle = int(sys.argv[1])
476475
else:
@@ -494,7 +493,7 @@ def init(self):
494493

495494
# after that try to get the params
496495
if num_args > 2:
497-
_params = to_unicode(sys.argv[2][1:])
496+
_params = sys.argv[2][1:]
498497
if _params:
499498
self._param_string = _params
500499
params.update(dict(parse_qsl(_params, keep_blank_values=True)))
@@ -727,7 +726,7 @@ def localize(self, text_id, args=None, default_text=None):
727726
else:
728727
self.log.warning(msg, text_id=text_id)
729728
return default_text
730-
result = to_unicode(result)
729+
result = result
731730

732731
if _args:
733732
if localize_args:

resources/lib/youtube_plugin/kodion/json_store/json_store.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
from io import open
1616

1717
from .. import logging
18+
from ..compatibility import to_unicode
1819
from ..constants import DATA_PATH, FILE_READ, FILE_WRITE
19-
from ..utils.convert_format import to_unicode
2020
from ..utils.file_system import make_dirs
2121
from ..utils.methods import merge_dicts
2222

resources/lib/youtube_plugin/kodion/logging.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
from sys import exc_info as sys_exc_info
1919
from traceback import extract_stack, format_list
2020

21-
from .compatibility import StringIO, string_type, to_str, xbmc
21+
from .compatibility import StringIO, string_type, to_str, to_unicode, xbmc
2222
from .constants import ADDON_ID
23-
from .utils.convert_format import to_unicode, urls_in_text
23+
from .utils.convert_format import urls_in_text
2424
from .utils.redact import (
2525
parse_and_redact_uri,
2626
redact_auth_header,

resources/lib/youtube_plugin/kodion/ui/xbmc/xbmc_context_ui.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
UPDATING,
4040
URI,
4141
)
42-
from ...utils.convert_format import to_unicode
4342

4443

4544
class XbmcContextUI(AbstractContextUI):
@@ -82,13 +81,9 @@ def create_progress_dialog(self,
8281
def on_keyboard_input(title, default='', hidden=False):
8382
# Starting with Gotham (13.X > ...)
8483
dialog = xbmcgui.Dialog()
85-
result = dialog.input(title,
86-
to_unicode(default),
87-
type=xbmcgui.INPUT_ALPHANUM)
84+
result = dialog.input(title, default, type=xbmcgui.INPUT_ALPHANUM)
8885
if result:
89-
text = to_unicode(result)
90-
return True, text
91-
86+
return True, result
9287
return False, ''
9388

9489
@staticmethod
@@ -97,7 +92,6 @@ def on_numeric_input(title, default=''):
9792
result = dialog.input(title, str(default), type=xbmcgui.INPUT_NUMERIC)
9893
if result:
9994
return True, int(result)
100-
10195
return False, None
10296

10397
@staticmethod
@@ -113,19 +107,19 @@ def on_ok(title, text):
113107
def on_remove_content(self, name):
114108
return self.on_yes_no_input(
115109
self._context.localize('content.remove'),
116-
self._context.localize('content.remove.check.x', to_unicode(name)),
110+
self._context.localize('content.remove.check.x', name),
117111
)
118112

119113
def on_delete_content(self, name):
120114
return self.on_yes_no_input(
121115
self._context.localize('content.delete'),
122-
self._context.localize('content.delete.check.x', to_unicode(name)),
116+
self._context.localize('content.delete.check.x', name),
123117
)
124118

125119
def on_clear_content(self, name):
126120
return self.on_yes_no_input(
127121
self._context.localize('content.clear'),
128-
self._context.localize('content.clear.check.x', to_unicode(name)),
122+
self._context.localize('content.clear.check.x', name),
129123
)
130124

131125
@staticmethod

0 commit comments

Comments
 (0)