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

v7.0.9.2 #889

Merged
merged 6 commits into from
Aug 25, 2024
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
2 changes: 1 addition & 1 deletion addon.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="plugin.video.youtube" name="YouTube" version="7.0.9.1" provider-name="anxdpanic, bromix, MoojMidge">
<addon id="plugin.video.youtube" name="YouTube" version="7.0.9.2" provider-name="anxdpanic, bromix, MoojMidge">
<requires>
<import addon="xbmc.python" version="3.0.0"/>
<import addon="script.module.requests" version="2.27.1"/>
Expand Down
6 changes: 6 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## v7.0.9.2
### Fixed
- Fix various Kodi 18 listitem setInfo compatibility issues
- Additional fixes and compatibility shims for playing AudioItems #873
- Fix early thread loop termination in My Subscriptions #888

## v7.0.9.1
### Fixed
- Add playlist_type_hint property to workaround issues with CPlayListPlayer::Play #873
Expand Down
6 changes: 3 additions & 3 deletions resources/lib/youtube_plugin/kodion/compatibility/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,9 @@ def to_str(value):

# Kodi v20+
if hasattr(xbmcgui.ListItem, 'setDateTime'):
def datetime_infolabel(datetime_obj):
def datetime_infolabel(datetime_obj, *_args, **_kwargs):
return datetime_obj.replace(microsecond=0, tzinfo=None).isoformat()
# Compatibility shims for Kodi v18 and v19
else:
def datetime_infolabel(datetime_obj):
return datetime_obj.strftime('%d.%m.%Y')
def datetime_infolabel(datetime_obj, str_format='%Y-%m-%d %H:%M:%S'):
return datetime_obj.strftime(str_format)
2 changes: 1 addition & 1 deletion resources/lib/youtube_plugin/kodion/items/base_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ def set_date_from_datetime(self, date_time):
def get_date(self, as_text=False, short=False, as_info_label=False):
if self._date:
if as_info_label:
return datetime_infolabel(self._date)
return datetime_infolabel(self._date, '%d.%m.%Y')
if short:
return self._date.date().strftime('%x')
if as_text:
Expand Down
6 changes: 3 additions & 3 deletions resources/lib/youtube_plugin/kodion/items/media_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ def set_mediatype(self, mediatype):
self._mediatype = self._DEFAULT_MEDIATYPE

def get_mediatype(self):
return self._mediatype
return self._mediatype or self._DEFAULT_MEDIATYPE

def set_plot(self, plot):
try:
Expand Down Expand Up @@ -381,7 +381,7 @@ def playlist_item_id(self, value):


class AudioItem(MediaItem):
_ALLOWABLE_MEDIATYPES = {'song', 'album', 'artist'}
_ALLOWABLE_MEDIATYPES = {CONTENT.AUDIO_TYPE, 'song', 'album', 'artist'}
_DEFAULT_MEDIATYPE = CONTENT.AUDIO_TYPE

def __init__(self, name, uri, image='DefaultAudio.png', fanart=None):
Expand All @@ -396,7 +396,7 @@ def get_album_name(self):


class VideoItem(MediaItem):
_ALLOWABLE_MEDIATYPES = {'video',
_ALLOWABLE_MEDIATYPES = {CONTENT.VIDEO_TYPE,
'movie',
'tvshow', 'season', 'episode',
'musicvideo'}
Expand Down
27 changes: 19 additions & 8 deletions resources/lib/youtube_plugin/kodion/items/xbmc/xbmc_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def set_info(list_item, item, properties, set_play_count=True, resume=True):
else:
return

value = item.get_artists_string()
value = item.get_artists()
if value is not None:
info_labels['artist'] = value

Expand Down Expand Up @@ -321,12 +321,20 @@ def set_info(list_item, item, properties, set_play_count=True, resume=True):

resume_time = resume and item.get_start_time()
duration = item.get_duration()
if resume_time and duration:
info_tag.setResumePoint(resume_time, float(duration))
elif resume_time:
info_tag.setResumePoint(resume_time)
if info_type == 'video' and duration:
info_tag.addVideoStream(xbmc.VideoStreamDetail(duration=duration))
if info_type == 'video':
if resume_time and duration:
info_tag.setResumePoint(resume_time, float(duration))
elif resume_time:
info_tag.setResumePoint(resume_time)
if duration:
info_tag.addVideoStream(xbmc.VideoStreamDetail(duration=duration))
elif info_type == 'music':
# These properties are deprecated but there is no other way to set these
# details for a ListItem with a MusicInfoTag
if resume_time:
properties['ResumeTime'] = str(resume_time)
if duration:
properties['TotalTime'] = str(duration)

# duration: int
# As seconds
Expand All @@ -346,7 +354,10 @@ def set_info(list_item, item, properties, set_play_count=True, resume=True):
value = item.get_play_count()
if value is not None:
if set_play_count:
info_tag.setPlaycount(value)
if info_type == 'video':
info_tag.setPlaycount(value)
elif info_type == 'music':
info_tag.setPlayCount(value)
properties[PLAY_COUNT] = value

# count: int
Expand Down
2 changes: 1 addition & 1 deletion resources/lib/youtube_plugin/kodion/network/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def cert_verify(self, conn, url, verify, cert):
self._ssl_context.check_hostname = bool(verify)
return super(SSLHTTPAdapter, self).cert_verify(conn, url, verify, cert)


class BaseRequestsClass(object):
_session = Session()
_session.mount('https://', SSLHTTPAdapter(
Expand All @@ -50,7 +51,6 @@ class BaseRequestsClass(object):
total=3,
backoff_factor=0.1,
status_forcelist={500, 502, 503, 504},
allowed_methods=None,
)
))
atexit.register(_session.close)
Expand Down
63 changes: 36 additions & 27 deletions resources/lib/youtube_plugin/youtube/client/youtube.py
Original file line number Diff line number Diff line change
Expand Up @@ -1636,15 +1636,14 @@ def _threaded_fetch(kwargs,
input_wait.release()
if kwargs:
continue
complete = True
break
else:
complete = True
break

try:
success, complete = worker(output, **_kwargs)
except Exception as exc:
except Exception:
msg = 'get_my_subscriptions._threaded_fetch - {exc}'
self._context.log_error(msg.format(exc=format_exc()))
continue
Expand All @@ -1654,31 +1653,35 @@ def _threaded_fetch(kwargs,
else:
threads['balance'].clear()

current_thread = threading.current_thread()
threads['available'].release()
threads['counter'].release()
if complete:
threads['pool_counts'][pool_id] = None
threads['counts'][pool_id] = None
else:
threads['pool_counts'][pool_id] -= 1
threads['pool_counts']['all'] -= 1
threads['current'].discard(current_thread)
threads['counts'][pool_id] -= 1
threads['counts']['all'] -= 1
threads['current'].discard(threading.current_thread())
threads['loop'].set()

try:
num_cores = cpu_count() or 1
except NotImplementedError:
num_cores = 1
max_threads = min(32, 2 * (num_cores + 4))
counts = {
'all': 0,
}
current_threads = set()
counter = threading.Semaphore(max_threads)
balance_enable = threading.Event()
loop_enable = threading.Event()
threads = {
'max': max_threads,
'available': threading.Semaphore(max_threads),
'current': set(),
'pool_counts': {
'all': 0,
},
'balance': threading.Event(),
'loop': threading.Event(),
'balance': balance_enable,
'loop': loop_enable,
'counter': counter,
'counts': counts,
'current': current_threads,
}

payloads = {}
if logged_in:
payloads[1] = {
Expand All @@ -1688,6 +1691,7 @@ def _threaded_fetch(kwargs,
'threads': threads,
'limit': 1,
'input_wait': None,
'input_wait_for': None,
}
payloads.update({
2: {
Expand All @@ -1697,6 +1701,7 @@ def _threaded_fetch(kwargs,
'threads': threads,
'limit': 1,
'input_wait': threading.Lock(),
'input_wait_for': 1,
},
3: {
'worker': _get_feed,
Expand All @@ -1705,18 +1710,19 @@ def _threaded_fetch(kwargs,
'threads': threads,
'limit': None,
'input_wait': threading.Lock(),
'input_wait_for': 2,
},
})

completed = []
iterator = iter(payloads)
threads['loop'].set()
while threads['loop'].wait():
loop_enable.set()
while loop_enable.wait():
try:
pool_id = next(iterator)
except StopIteration:
threads['loop'].clear()
if not threads['current']:
loop_enable.clear()
if not current_threads:
break
for pool_id in completed:
del payloads[pool_id]
Expand All @@ -1726,7 +1732,7 @@ def _threaded_fetch(kwargs,

payload = payloads[pool_id]
payload['pool_id'] = pool_id
current_num = threads['pool_counts'].setdefault(pool_id, 0)
current_num = counts.setdefault(pool_id, 0)
if current_num is None:
completed.append(pool_id)
continue
Expand All @@ -1736,15 +1742,18 @@ def _threaded_fetch(kwargs,
if input_wait and input_wait.locked():
input_wait.release()
else:
input_wait_for = payload['input_wait_for']
if not input_wait_for or input_wait_for not in payloads:
completed.append(pool_id)
continue

available = threads['max'] - threads['pool_counts']['all']
available = max_threads - counts['all']
limit = payload['limit']
if limit:
if current_num >= limit:
continue
if available <= 0:
threads['balance'].set()
balance_enable.set()
elif available <= 0:
continue

Expand All @@ -1753,10 +1762,10 @@ def _threaded_fetch(kwargs,
kwargs=payload,
)
new_thread.daemon = True
threads['current'].add(new_thread)
threads['pool_counts'][pool_id] += 1
threads['pool_counts']['all'] += 1
threads['available'].acquire(True)
current_threads.add(new_thread)
counts[pool_id] += 1
counts['all'] += 1
counter.acquire(True)
new_thread.start()

items = _parse_feeds(threaded_output['feeds'])
Expand Down
6 changes: 4 additions & 2 deletions resources/lib/youtube_plugin/youtube/helper/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from math import log10

from ...kodion.constants import CONTENT, LICENSE_TOKEN, LICENSE_URL, PATHS
from ...kodion.items import DirectoryItem, menu_items
from ...kodion.items import AudioItem, DirectoryItem, menu_items
from ...kodion.utils import (
datetime_parser,
friendly_number,
Expand Down Expand Up @@ -431,7 +431,9 @@ def update_video_infos(provider, context, video_id_dict,

media_item = video_id_dict[video_id]
media_item.set_mediatype(
CONTENT.AUDIO_TYPE if audio_only else CONTENT.VIDEO_TYPE
CONTENT.AUDIO_TYPE
if audio_only or isinstance(media_item, AudioItem) else
CONTENT.VIDEO_TYPE
)

play_data = use_play_data and yt_item.get('play_data')
Expand Down
Loading