Skip to content

Commit

Permalink
Use consistent return values for function cache to avoid caching errors
Browse files Browse the repository at this point in the history
  • Loading branch information
MoojMidge committed May 31, 2024
1 parent 84f4730 commit 7db63bf
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 40 deletions.
2 changes: 1 addition & 1 deletion resources/lib/youtube_plugin/kodion/abstract_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ def reroute(self, context, re_match=None, path=None, params=None):
result, options = function_cache.run(
self.navigate,
seconds=None,
_cacheparams=function_cache.PARAMS_NONE,
_refresh=True,
_scope=function_cache.SCOPE_NONE,
context=context.clone(path, params),
)
finally:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ def run(self, provider, context, focused=None):
result, options = function_cache.run(
provider.navigate,
seconds=None,
_cacheparams=function_cache.PARAMS_NONE,
_oneshot=True,
_scope=function_cache.SCOPE_NONE,
context=context.clone(route),
)
ui.clear_property(REROUTE)
Expand Down
35 changes: 21 additions & 14 deletions resources/lib/youtube_plugin/kodion/sql_store/function_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ class FunctionCache(Storage):
_sql = {}

_BUILTIN = str.__module__
PARAMS_NONE = 0
PARAMS_BUILTINS = 1
PARAMS_ALL = 2
SCOPE_NONE = 0
SCOPE_BUILTINS = 1
SCOPE_ALL = 2

def __init__(self, filepath, max_file_size_mb=5):
max_file_size_kb = max_file_size_mb * 1024
Expand All @@ -49,7 +49,7 @@ def disable(self):
self._enabled = False

@classmethod
def _create_id_from_func(cls, partial_func, hash_params=PARAMS_ALL):
def _create_id_from_func(cls, partial_func, scope=SCOPE_ALL):
"""
Creates an id from the given function
:param partial_func:
Expand All @@ -60,7 +60,7 @@ def _create_id_from_func(cls, partial_func, hash_params=PARAMS_ALL):
partial_func.func.__module__,
partial_func.func.__name__,
)
if hash_params == cls.PARAMS_BUILTINS:
if scope == cls.SCOPE_BUILTINS:
signature = chain(
signature,
((
Expand All @@ -74,7 +74,7 @@ def _create_id_from_func(cls, partial_func, hash_params=PARAMS_ALL):
(key, type(arg))
) for key, arg in partial_func.keywords.items()),
)
elif hash_params == cls.PARAMS_ALL:
elif scope == cls.SCOPE_ALL:
signature = chain(
signature,
partial_func.args,
Expand All @@ -101,27 +101,34 @@ def run(self, func, seconds, *args, **kwargs):
:param int|None seconds: max allowable age of cached result
:param tuple args: positional arguments passed to the function
:param dict kwargs: keyword arguments passed to the function
:keyword _cacheparams: (int) cache result for function and parameters.
0: function only,
1: include value of builtin type parameters
2: include value of all parameters, default 2
:keyword _scope: (int) cache result if matching:
0: function only,
1: function + value of builtin type parameters
2: function + value of all parameters, default 2
:keyword _ignore_value: (Any) don't cache func return value if equal to
_ignored_value, default None
:keyword _oneshot: (bool) remove previously cached result, default False
:keyword _refresh: (bool) updates cache with new result, default False
:keyword _retry_value: (Any) re-evaluate func if cached value is equal
_retry_value, default None
:return:
"""
cache_params = kwargs.pop('_cacheparams', self.PARAMS_ALL)
scope = kwargs.pop('_scope', self.SCOPE_ALL)
ignore_value = kwargs.pop('_ignore_value', None)
oneshot = kwargs.pop('_oneshot', False)
refresh = kwargs.pop('_refresh', False)
retry_value = kwargs.pop('_retry_value', None)
partial_func = partial(func, *args, **kwargs)

# if caching is disabled call the function
if not self._enabled:
return partial_func()

cache_id = self._create_id_from_func(partial_func, cache_params)
data = None if refresh else self._get(cache_id, seconds=seconds)
if data is None:
cache_id = self._create_id_from_func(partial_func, scope)
data = retry_value if refresh else self._get(cache_id, seconds=seconds)
if data == retry_value:
data = partial_func()
if data != ignore_value:
self._set(cache_id, data)
elif oneshot:
self._remove(cache_id)
Expand Down
25 changes: 14 additions & 11 deletions resources/lib/youtube_plugin/youtube/client/youtube.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,11 +486,6 @@ def get_recommended_for_home(self,
visitor='',
page_token='',
click_tracking=''):
payload = {
'kind': 'youtube#activityListResponse',
'items': []
}

post_data = {'browseId': 'FEwhat_to_watch'}
if page_token:
post_data['continuation'] = page_token
Expand All @@ -511,7 +506,7 @@ def get_recommended_for_home(self,
path='browse',
post_data=post_data)
if not result:
return payload
return None

recommended_videos = self.json_traverse(
result,
Expand Down Expand Up @@ -565,7 +560,7 @@ def get_recommended_for_home(self,
)
)
if not recommended_videos:
return payload
return None

v3_response = {
'kind': 'youtube#activityListResponse',
Expand Down Expand Up @@ -611,6 +606,8 @@ def get_recommended_for_home(self,
if visitor:
v3_response['visitorData'] = visitor

if not v3_response['items']:
v3_response = None
return v3_response

def get_related_for_home(self, page_token='', refresh=False):
Expand Down Expand Up @@ -1104,7 +1101,7 @@ def get_related_videos(self,
post_data=post_data,
no_login=True)
if not result:
return {}
return None

related_videos = self.json_traverse(result, path=(
(
Expand Down Expand Up @@ -1270,14 +1267,17 @@ def get_related_videos(self,
max_results=remaining,
**kwargs
)
if 'nextPageToken' in continuation:
if continuation and 'nextPageToken' in continuation:
page_token = continuation['nextPageToken']
else:
page_token = ''
if 'items' in continuation:
items.extend(continuation['items'])

v3_response['items'] = items
if items:
v3_response['items'] = items
else:
v3_response = None
return v3_response

def get_parent_comments(self,
Expand Down Expand Up @@ -1744,7 +1744,10 @@ def _sort_by_date_time(item, limits=limits):
else:
items = []

v3_response['items'] = items
if items:
v3_response['items'] = items
else:
v3_response = None
return v3_response

def get_saved_playlists(self, page_token, offset):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,8 @@ def get_related_playlists(self, channel_id, defer_cache=False):
break

if item is None:
return {}

return item.get('contentDetails', {}).get('relatedPlaylists', {})
return None
return item.get('contentDetails', {}).get('relatedPlaylists')

def get_videos(self,
ids,
Expand Down
6 changes: 3 additions & 3 deletions resources/lib/youtube_plugin/youtube/helper/yt_playlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,14 +181,15 @@ def _process_select_playlist(provider, context):
thumb_size = context.get_settings().get_thumbnail_size()
default_thumb = context.create_resource_path('media', 'playlist.png')

while True:
while 1:
current_page += 1
json_data = function_cache.run(client.get_playlists_of_channel,
function_cache.ONE_MINUTE // 3,
_refresh=params.get('refresh'),
channel_id='mine',
page_token=page_token)

if not json_data:
break
playlists = json_data.get('items', [])
page_token = json_data.get('nextPageToken', '')

Expand Down Expand Up @@ -252,7 +253,6 @@ def _process_select_playlist(provider, context):
new_params = dict(context.get_params(), playlist_id=result)
new_context = context.clone(new_params=new_params)
_process_add_video(provider, new_context, keymap_action)
break
break


Expand Down
3 changes: 2 additions & 1 deletion resources/lib/youtube_plugin/youtube/helper/yt_specials.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ def _process_browse_channels(provider, context, client):
else:
function_cache = context.get_function_cache()
json_data = function_cache.run(client.get_guide_categories,
function_cache.ONE_MONTH)
function_cache.ONE_MONTH,
_refresh=context.get_param('refresh'))

if not json_data:
return False
Expand Down
10 changes: 4 additions & 6 deletions resources/lib/youtube_plugin/youtube/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,12 +413,11 @@ def _on_channel_live(self, context, re_match):
playlists = function_cache.run(resource_manager.get_related_playlists,
function_cache.ONE_DAY,
channel_id=channel_id)
upload_playlist = playlists.get('uploads', '')
if upload_playlist:
if playlists and 'uploads' in playlists:
json_data = function_cache.run(client.get_playlist_items,
function_cache.ONE_MINUTE * 5,
_refresh=params.get('refresh'),
playlist_id=upload_playlist,
playlist_id=playlists['uploads'],
page_token=page_token)
if not json_data:
return result
Expand Down Expand Up @@ -558,12 +557,11 @@ def _on_channel(self, context, re_match):
playlists = function_cache.run(resource_manager.get_related_playlists,
function_cache.ONE_DAY,
channel_id=channel_id)
upload_playlist = playlists.get('uploads', '')
if upload_playlist:
if playlists and 'uploads' in playlists:
json_data = function_cache.run(client.get_playlist_items,
function_cache.ONE_MINUTE * 5,
_refresh=params.get('refresh'),
playlist_id=upload_playlist,
playlist_id=playlists['uploads'],
page_token=page_token)
if not json_data:
return result
Expand Down

0 comments on commit 7db63bf

Please sign in to comment.