Skip to content

Commit d3832c2

Browse files
committed
[script.module.youtube.dl@matrix] 25.05.18+matrix.1
based on GIT dated of May 18 2025
1 parent 37c81ec commit d3832c2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+7484
-2381
lines changed

script.module.youtube.dl/addon.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2-
<addon id="script.module.youtube.dl" name="youtube-dl Control" version="23.04.01+matrix.1" provider-name="ytdl-org,ruuk,sy6sy2,wwark">
2+
<addon id="script.module.youtube.dl" name="youtube-dl Control" version="25.05.18+matrix.1" provider-name="ytdl-org,ruuk,sy6sy2,wwark">
33
<requires>
44
<import addon="xbmc.python" version="3.0.0"/>
55
<import addon="script.module.addon.signals" version="0.0.5+matrix.1"/>

script.module.youtube.dl/lib/youtube_dl/YoutubeDL.py

Lines changed: 339 additions & 122 deletions
Large diffs are not rendered by default.

script.module.youtube.dl/lib/youtube_dl/__init__.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
__license__ = 'Public Domain'
77

8-
import codecs
98
import io
109
import os
1110
import random
@@ -17,10 +16,12 @@
1716
)
1817
from .compat import (
1918
compat_getpass,
19+
compat_register_utf8,
2020
compat_shlex_split,
21-
workaround_optparse_bug9161,
21+
_workaround_optparse_bug9161,
2222
)
2323
from .utils import (
24+
_UnsafeExtensionError,
2425
DateRange,
2526
decodeOption,
2627
DEFAULT_OUTTMPL,
@@ -46,12 +47,10 @@
4647

4748

4849
def _real_main(argv=None):
49-
# Compatibility fixes for Windows
50-
if sys.platform == 'win32':
51-
# https://github.com/ytdl-org/youtube-dl/issues/820
52-
codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None)
50+
# Compatibility fix for Windows
51+
compat_register_utf8()
5352

54-
workaround_optparse_bug9161()
53+
_workaround_optparse_bug9161()
5554

5655
setproctitle('youtube-dl')
5756

@@ -175,6 +174,9 @@ def _real_main(argv=None):
175174
if opts.ap_mso and opts.ap_mso not in MSO_INFO:
176175
parser.error('Unsupported TV Provider, use --ap-list-mso to get a list of supported TV Providers')
177176

177+
if opts.no_check_extensions:
178+
_UnsafeExtensionError.lenient = True
179+
178180
def parse_retries(retries):
179181
if retries in ('inf', 'infinite'):
180182
parsed_retries = float('inf')

script.module.youtube.dl/lib/youtube_dl/__main__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# direct call of __main__.py
1212
import os.path
1313
path = os.path.realpath(os.path.abspath(__file__))
14+
sys.path.insert(0, os.path.dirname(os.path.dirname(path)))
1415

1516
import youtube_dl
1617

Lines changed: 66 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
1+
# coding: utf-8
12
from __future__ import unicode_literals
23

34
import errno
4-
import io
55
import json
66
import os
77
import re
88
import shutil
99
import traceback
1010

11-
from .compat import compat_getenv
11+
from .compat import (
12+
compat_getenv,
13+
compat_open as open,
14+
compat_os_makedirs,
15+
)
1216
from .utils import (
1317
error_to_compat_str,
18+
escape_rfc3986,
1419
expand_path,
1520
is_outdated_version,
16-
try_get,
21+
traverse_obj,
1722
write_json_file,
1823
)
1924
from .version import __version__
@@ -28,23 +33,35 @@ class Cache(object):
2833
def __init__(self, ydl):
2934
self._ydl = ydl
3035

36+
def _write_debug(self, *args, **kwargs):
37+
self._ydl.write_debug(*args, **kwargs)
38+
39+
def _report_warning(self, *args, **kwargs):
40+
self._ydl.report_warning(*args, **kwargs)
41+
42+
def _to_screen(self, *args, **kwargs):
43+
self._ydl.to_screen(*args, **kwargs)
44+
45+
def _get_param(self, k, default=None):
46+
return self._ydl.params.get(k, default)
47+
3148
def _get_root_dir(self):
32-
res = self._ydl.params.get('cachedir')
49+
res = self._get_param('cachedir')
3350
if res is None:
3451
cache_root = compat_getenv('XDG_CACHE_HOME', '~/.cache')
3552
res = os.path.join(cache_root, self._YTDL_DIR)
3653
return expand_path(res)
3754

3855
def _get_cache_fn(self, section, key, dtype):
39-
assert re.match(r'^[a-zA-Z0-9_.-]+$', section), \
56+
assert re.match(r'^[\w.-]+$', section), \
4057
'invalid section %r' % section
41-
assert re.match(r'^[a-zA-Z0-9_.-]+$', key), 'invalid key %r' % key
58+
key = escape_rfc3986(key, safe='').replace('%', ',') # encode non-ascii characters
4259
return os.path.join(
4360
self._get_root_dir(), section, '%s.%s' % (key, dtype))
4461

4562
@property
4663
def enabled(self):
47-
return self._ydl.params.get('cachedir') is not False
64+
return self._get_param('cachedir') is not False
4865

4966
def store(self, section, key, data, dtype='json'):
5067
assert dtype in ('json',)
@@ -54,61 +71,75 @@ def store(self, section, key, data, dtype='json'):
5471

5572
fn = self._get_cache_fn(section, key, dtype)
5673
try:
57-
try:
58-
os.makedirs(os.path.dirname(fn))
59-
except OSError as ose:
60-
if ose.errno != errno.EEXIST:
61-
raise
74+
compat_os_makedirs(os.path.dirname(fn), exist_ok=True)
75+
self._write_debug('Saving {section}.{key} to cache'.format(section=section, key=key))
6276
write_json_file({self._VERSION_KEY: __version__, 'data': data}, fn)
6377
except Exception:
6478
tb = traceback.format_exc()
65-
self._ydl.report_warning(
66-
'Writing cache to %r failed: %s' % (fn, tb))
79+
self._report_warning('Writing cache to {fn!r} failed: {tb}'.format(fn=fn, tb=tb))
80+
81+
def clear(self, section, key, dtype='json'):
82+
83+
if not self.enabled:
84+
return
85+
86+
fn = self._get_cache_fn(section, key, dtype)
87+
self._write_debug('Clearing {section}.{key} from cache'.format(section=section, key=key))
88+
try:
89+
os.remove(fn)
90+
except Exception as e:
91+
if getattr(e, 'errno') == errno.ENOENT:
92+
# file not found
93+
return
94+
tb = traceback.format_exc()
95+
self._report_warning('Clearing cache from {fn!r} failed: {tb}'.format(fn=fn, tb=tb))
6796

6897
def _validate(self, data, min_ver):
69-
version = try_get(data, lambda x: x[self._VERSION_KEY])
98+
version = traverse_obj(data, self._VERSION_KEY)
7099
if not version: # Backward compatibility
71100
data, version = {'data': data}, self._DEFAULT_VERSION
72101
if not is_outdated_version(version, min_ver or '0', assume_new=False):
73102
return data['data']
74-
self._ydl.to_screen(
75-
'Discarding old cache from version {version} (needs {min_ver})'.format(**locals()))
103+
self._write_debug('Discarding old cache from version {version} (needs {min_ver})'.format(version=version, min_ver=min_ver))
76104

77-
def load(self, section, key, dtype='json', default=None, min_ver=None):
105+
def load(self, section, key, dtype='json', default=None, **kw_min_ver):
78106
assert dtype in ('json',)
107+
min_ver = kw_min_ver.get('min_ver')
79108

80109
if not self.enabled:
81110
return default
82111

83112
cache_fn = self._get_cache_fn(section, key, dtype)
84113
try:
114+
with open(cache_fn, encoding='utf-8') as cachef:
115+
self._write_debug('Loading {section}.{key} from cache'.format(section=section, key=key), only_once=True)
116+
return self._validate(json.load(cachef), min_ver)
117+
except (ValueError, KeyError):
85118
try:
86-
with io.open(cache_fn, 'r', encoding='utf-8') as cachef:
87-
return self._validate(json.load(cachef), min_ver)
88-
except ValueError:
89-
try:
90-
file_size = os.path.getsize(cache_fn)
91-
except (OSError, IOError) as oe:
92-
file_size = error_to_compat_str(oe)
93-
self._ydl.report_warning(
94-
'Cache retrieval from %s failed (%s)' % (cache_fn, file_size))
95-
except IOError:
96-
pass # No cache available
119+
file_size = 'size: %d' % os.path.getsize(cache_fn)
120+
except (OSError, IOError) as oe:
121+
file_size = error_to_compat_str(oe)
122+
self._report_warning('Cache retrieval from %s failed (%s)' % (cache_fn, file_size))
123+
except Exception as e:
124+
if getattr(e, 'errno') == errno.ENOENT:
125+
# no cache available
126+
return
127+
self._report_warning('Cache retrieval from %s failed' % (cache_fn,))
97128

98129
return default
99130

100131
def remove(self):
101132
if not self.enabled:
102-
self._ydl.to_screen('Cache is disabled (Did you combine --no-cache-dir and --rm-cache-dir?)')
133+
self._to_screen('Cache is disabled (Did you combine --no-cache-dir and --rm-cache-dir?)')
103134
return
104135

105136
cachedir = self._get_root_dir()
106137
if not any((term in cachedir) for term in ('cache', 'tmp')):
107-
raise Exception('Not removing directory %s - this does not look like a cache dir' % cachedir)
138+
raise Exception('Not removing directory %s - this does not look like a cache dir' % (cachedir,))
108139

109-
self._ydl.to_screen(
110-
'Removing cache dir %s .' % cachedir, skip_eol=True)
140+
self._to_screen(
141+
'Removing cache dir %s .' % (cachedir,), skip_eol=True, ),
111142
if os.path.exists(cachedir):
112-
self._ydl.to_screen('.', skip_eol=True)
143+
self._to_screen('.', skip_eol=True)
113144
shutil.rmtree(cachedir)
114-
self._ydl.to_screen('.')
145+
self._to_screen('.')

script.module.youtube.dl/lib/youtube_dl/casefold.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010
# https://github.com/unicode-org/icu/blob/main/icu4c/source/data/unidata/CaseFolding.txt
1111
# In case newly foldable Unicode characters are defined, paste the new version
1212
# of the text inside the ''' marks.
13-
# The text is expected to have only blank lines andlines with 1st character #,
13+
# The text is expected to have only blank lines and lines with 1st character #,
1414
# all ignored, and fold definitions like this:
15-
# `from_hex_code; space_separated_to_hex_code_list; comment`
15+
# `from_hex_code; status; space_separated_to_hex_code_list; comment`
16+
# Only `status` C/F are used.
1617

1718
_map_str = '''
1819
# CaseFolding-15.0.0.txt
@@ -1657,11 +1658,6 @@ def _parse_unichr(s):
16571658
del _map_str
16581659

16591660

1660-
def casefold(s):
1661+
def _casefold(s):
16611662
assert isinstance(s, compat_str)
16621663
return ''.join((_map.get(c, c) for c in s))
1663-
1664-
1665-
__all__ = [
1666-
casefold
1667-
]

0 commit comments

Comments
 (0)