Fix empty My List due to unknown items (#102)
* Ignore unavailable items on My List * Rework My List API
This commit is contained in:
parent
21f877fb8d
commit
02b2d4dbb1
@ -4,9 +4,6 @@
|
||||
from __future__ import absolute_import, division, unicode_literals
|
||||
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
import dateutil.tz
|
||||
|
||||
from resources.lib import kodiutils
|
||||
from resources.lib.kodiutils import TitleItem
|
||||
@ -253,22 +250,10 @@ class Catalog:
|
||||
kodiutils.show_listing(listing, 30005, content='tvshows')
|
||||
|
||||
def show_mylist(self):
|
||||
""" Show all the programs of all channels """
|
||||
try:
|
||||
mylist, _ = self._auth.get_dataset('myList', 'myList')
|
||||
except Exception as ex:
|
||||
kodiutils.notification(message=str(ex))
|
||||
raise
|
||||
""" Show the programs of My List """
|
||||
mylist = self._api.get_mylist()
|
||||
|
||||
items = []
|
||||
if mylist:
|
||||
for item in mylist:
|
||||
program = self._api.get_program_by_uuid(item.get('id'))
|
||||
if program:
|
||||
program.my_list = True
|
||||
items.append(program)
|
||||
|
||||
listing = [Menu.generate_titleitem(item) for item in items]
|
||||
listing = [Menu.generate_titleitem(item) for item in mylist]
|
||||
|
||||
# Sort items by title
|
||||
# Used for A-Z listing or when movies and episodes are mixed.
|
||||
@ -280,23 +265,7 @@ class Catalog:
|
||||
kodiutils.end_of_directory()
|
||||
return
|
||||
|
||||
mylist, sync_info = self._auth.get_dataset('myList', 'myList')
|
||||
|
||||
if not mylist:
|
||||
mylist = []
|
||||
|
||||
if uuid not in [item.get('id') for item in mylist]:
|
||||
# Python 2.7 doesn't support .timestamp(), and windows doesn't do '%s', so we need to calculate it ourself
|
||||
epoch = datetime(1970, 1, 1, tzinfo=dateutil.tz.gettz('UTC'))
|
||||
now = datetime.now(tz=dateutil.tz.gettz('UTC'))
|
||||
timestamp = int((now - epoch).total_seconds()) * 1000
|
||||
|
||||
mylist.append({
|
||||
'id': uuid,
|
||||
'timestamp': timestamp,
|
||||
})
|
||||
|
||||
self._auth.put_dataset('myList', 'myList', mylist, sync_info)
|
||||
self._api.mylist_add(uuid)
|
||||
|
||||
kodiutils.end_of_directory()
|
||||
|
||||
@ -306,12 +275,6 @@ class Catalog:
|
||||
kodiutils.end_of_directory()
|
||||
return
|
||||
|
||||
mylist, sync_info = self._auth.get_dataset('myList', 'myList')
|
||||
|
||||
if not mylist:
|
||||
mylist = []
|
||||
|
||||
new_mylist = [item for item in mylist if item.get('id') != uuid]
|
||||
self._auth.put_dataset('myList', 'myList', new_mylist, sync_info)
|
||||
self._api.mylist_del(uuid)
|
||||
|
||||
kodiutils.end_of_directory()
|
||||
|
@ -354,7 +354,7 @@ class ContentApi:
|
||||
:type uuid: str
|
||||
:rtype str
|
||||
"""
|
||||
response = self._get_url(self.API_VIERVIJFZES + '/content/%s' % uuid, authentication=True)
|
||||
response = self._get_url(self.API_VIERVIJFZES + '/content/%s' % uuid, authentication=self._auth.get_token())
|
||||
data = json.loads(response)
|
||||
|
||||
if not data:
|
||||
@ -366,7 +366,7 @@ class ContentApi:
|
||||
drm_key = data['drmKey']['S']
|
||||
|
||||
_LOGGER.debug('Fetching Authentication XML with drm_key %s', drm_key)
|
||||
response_drm = self._get_url(self.API_GOPLAY + '/video/xml/%s' % drm_key, authentication=True)
|
||||
response_drm = self._get_url(self.API_GOPLAY + '/video/xml/%s' % drm_key, authentication=self._auth.get_token())
|
||||
data_drm = json.loads(response_drm)
|
||||
|
||||
return ResolvedStream(
|
||||
@ -484,6 +484,33 @@ class ContentApi:
|
||||
|
||||
return categories
|
||||
|
||||
def get_mylist(self):
|
||||
""" Get the content of My List
|
||||
:rtype list[Program]
|
||||
"""
|
||||
data = self._get_url(self.API_GOPLAY + '/my-list', authentication='Bearer %s' % self._auth.get_token())
|
||||
result = json.loads(data)
|
||||
|
||||
items = []
|
||||
for item in result:
|
||||
try:
|
||||
program = self.get_program_by_uuid(item.get('programId'))
|
||||
if program:
|
||||
program.my_list = True
|
||||
items.append(program)
|
||||
except Exception as exc: # pylint: disable=broad-except
|
||||
_LOGGER.warning(exc)
|
||||
|
||||
return items
|
||||
|
||||
def mylist_add(self, program_id):
|
||||
""" Add a program on My List """
|
||||
self._post_url(self.API_GOPLAY + '/my-list', data={'programId': program_id}, authentication='Bearer %s' % self._auth.get_token())
|
||||
|
||||
def mylist_del(self, program_id):
|
||||
""" Remove a program on My List """
|
||||
self._delete_url(self.API_GOPLAY + '/my-list-item', params={'programId': program_id}, authentication='Bearer %s' % self._auth.get_token())
|
||||
|
||||
@staticmethod
|
||||
def _extract_programs(html):
|
||||
""" Extract Programs from HTML code
|
||||
@ -669,16 +696,15 @@ class ContentApi:
|
||||
)
|
||||
return episode
|
||||
|
||||
def _get_url(self, url, params=None, authentication=False):
|
||||
def _get_url(self, url, params=None, authentication=None):
|
||||
""" Makes a GET request for the specified URL.
|
||||
:type url: str
|
||||
:type authentication: str
|
||||
:rtype str
|
||||
"""
|
||||
if authentication:
|
||||
if not self._auth:
|
||||
raise Exception('Requested to authenticate, but not auth object passed')
|
||||
response = self._session.get(url, params=params, headers={
|
||||
'authorization': self._auth.get_token(),
|
||||
'authorization': authentication,
|
||||
})
|
||||
else:
|
||||
response = self._session.get(url, params=params)
|
||||
@ -689,6 +715,44 @@ class ContentApi:
|
||||
|
||||
return response.text
|
||||
|
||||
def _post_url(self, url, params=None, data=None, authentication=None):
|
||||
""" Makes a POST request for the specified URL.
|
||||
:type url: str
|
||||
:type authentication: str
|
||||
:rtype str
|
||||
"""
|
||||
if authentication:
|
||||
response = self._session.post(url, params=params, json=data, headers={
|
||||
'authorization': authentication,
|
||||
})
|
||||
else:
|
||||
response = self._session.post(url, params=params, json=data)
|
||||
|
||||
if response.status_code != 200:
|
||||
_LOGGER.error(response.text)
|
||||
raise Exception('Could not fetch data')
|
||||
|
||||
return response.text
|
||||
|
||||
def _delete_url(self, url, params=None, authentication=None):
|
||||
""" Makes a DELETE request for the specified URL.
|
||||
:type url: str
|
||||
:type authentication: str
|
||||
:rtype str
|
||||
"""
|
||||
if authentication:
|
||||
response = self._session.delete(url, params=params, headers={
|
||||
'authorization': authentication,
|
||||
})
|
||||
else:
|
||||
response = self._session.delete(url, params=params)
|
||||
|
||||
if response.status_code != 200:
|
||||
_LOGGER.error(response.text)
|
||||
raise Exception('Could not fetch data')
|
||||
|
||||
return response.text
|
||||
|
||||
def _handle_cache(self, key, cache_mode, update, ttl=30 * 24 * 60 * 60):
|
||||
""" Fetch something from the cache, and update if needed """
|
||||
if cache_mode in [CACHE_AUTO, CACHE_ONLY]:
|
||||
|
Loading…
Reference in New Issue
Block a user