Skip to content
Open
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
7 changes: 7 additions & 0 deletions resources/lib/addon.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ def auth_clear_cache():
Authentication().clear_cache()


@routing.route('/catalog/detail/<detail>')
def show_catalog_detail(detail):
""" Show a detail page that can be a Movie or a Program """
from resources.lib.modules.catalog import Catalog
Catalog().show_detail(detail)


@routing.route('/catalog/program/<program>')
def show_catalog_program(program):
""" Show a program from the catalog """
Expand Down
32 changes: 28 additions & 4 deletions resources/lib/modules/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from resources.lib import kodiutils
from resources.lib.kodiutils import TitleItem
from resources.lib.modules.menu import Menu
from resources.lib.streamz import STOREFRONT_MAIN, STOREFRONT_MOVIES, STOREFRONT_PAGE_CONTINUE_WATCHING, STOREFRONT_SERIES, Category
from resources.lib.streamz import STOREFRONT_MAIN, STOREFRONT_MOVIES, STOREFRONT_SERIES, Category, Movie
from resources.lib.streamz.api import CACHE_PREVENT, Api
from resources.lib.streamz.auth import Auth
from resources.lib.streamz.exceptions import UnavailableException
Expand All @@ -24,13 +24,33 @@ def __init__(self):
auth = Auth(kodiutils.get_tokens_path())
self._api = Api(auth.get_tokens())

def show_program(self, program):
def show_detail(self, detail):
""" Show a detail page. A Program shows its seasons, a Movie shows a single playable item.

:type detail: str
"""
try:
detail_obj = self._api.get_detail(detail, cache=CACHE_PREVENT) # Use CACHE_PREVENT since we want fresh data
except UnavailableException:
kodiutils.ok_dialog(message=kodiutils.localize(30712)) # The video is unavailable and can't be played right now.
kodiutils.end_of_directory()
return

if isinstance(detail_obj, Movie):
kodiutils.show_listing([Menu.generate_titleitem(detail_obj)], detail_obj.name, content='movies')
return

self.show_program(detail, program_obj=detail_obj)

def show_program(self, program, program_obj=None):
""" Show a program from the catalog.

:type program: str
:type program_obj: Program
"""
try:
program_obj = self._api.get_program(program, cache=CACHE_PREVENT) # Use CACHE_PREVENT since we want fresh data
if program_obj is None:
program_obj = self._api.get_program(program, cache=CACHE_PREVENT) # Use CACHE_PREVENT since we want fresh data
except UnavailableException:
kodiutils.ok_dialog(message=kodiutils.localize(30712)) # The video is unavailable and can't be played right now.
kodiutils.end_of_directory()
Expand Down Expand Up @@ -201,7 +221,11 @@ def mylist_del(self, content_id):

def show_continuewatching(self):
""" Show the items in "Continue Watching". """
category = self._api.get_storefront_category(STOREFRONT_MAIN, STOREFRONT_PAGE_CONTINUE_WATCHING)
category_id = self._api.get_continue_watching_id()
if not category_id:
kodiutils.show_listing([], 30019, content='episodes')
return
category = self._api.get_storefront_category(STOREFRONT_MAIN, category_id)

listing = []
for item in category.content:
Expand Down
28 changes: 27 additions & 1 deletion resources/lib/modules/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from resources.lib import kodiutils
from resources.lib.kodiutils import TitleItem
from resources.lib.streamz import (PRODUCT_STREAMZ, PRODUCT_STREAMZ_KIDS, STOREFRONT_KIDS, STOREFRONT_MAIN, STOREFRONT_MAIN_KIDS, STOREFRONT_MOVIES,
STOREFRONT_SERIES, Episode, Movie, Program)
STOREFRONT_SERIES, Episode, Movie, Program, Teaser)
from resources.lib.streamz.auth import Auth

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -240,6 +240,32 @@ def generate_titleitem(cls, item, progress=False):
is_playable=True,
)

#
# Teaser (a Movie or a Program, we only know once we open it)
#
if isinstance(item, Teaser):
if item.my_list:
context_menu = [(
kodiutils.localize(30101), # Remove from My List
'Container.Update(%s)' %
kodiutils.url_for('mylist_del', content_id=item.detail_id)
)]
else:
context_menu = [(
kodiutils.localize(30100), # Add to My List
'Container.Update(%s)' %
kodiutils.url_for('mylist_add', content_id=item.detail_id)
)]

return TitleItem(
title=item.name,
path=kodiutils.url_for('show_catalog_detail', detail=item.detail_id),
art_dict=art_dict,
info_dict=info_dict,
prop_dict=prop_dict,
context_menu=context_menu,
)

#
# Program
#
Expand Down
9 changes: 8 additions & 1 deletion resources/lib/modules/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,15 @@ def play(self, category, item):
return

try:
# Movies are opened by their detail id, but are played by their playable id
stream_id = item
if category in ['movies', 'oneoffs']:
movie = self._api.get_movie(item)
if movie and movie.playable_id:
stream_id = movie.playable_id

# Get stream information
resolved_stream = self._stream.get_stream(category, item)
resolved_stream = self._stream.get_stream(category, stream_id)

except UnavailableException:
kodiutils.ok_dialog(message=kodiutils.localize(30712)) # The video is unavailable...
Expand Down
34 changes: 31 additions & 3 deletions resources/lib/streamz/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@

# These seem to be hardcoded
STOREFRONT_MAIN = 'main'
STOREFRONT_MOVIES = 'movies'
STOREFRONT_MOVIES = 'films'
STOREFRONT_SERIES = 'series'
STOREFRONT_KIDS = 'kids'
STOREFRONT_MAIN_KIDS = 'main'

STOREFRONT_PAGE_CONTINUE_WATCHING = '7574469c-5d78-4878-84f5-c5729442eee4'

PRODUCT_STREAMZ = 'STREAMZ'
PRODUCT_STREAMZ_KIDS = 'STREAMZ_KIDS'
Expand Down Expand Up @@ -66,7 +65,7 @@ class Movie:
""" Defines a Movie """

def __init__(self, movie_id=None, name=None, description=None, year=None, poster=None, thumb=None, fanart=None, duration=None,
remaining=None, geoblocked=None, channel=None, legal=None, aired=None, my_list=None, available=True):
remaining=None, geoblocked=None, channel=None, legal=None, aired=None, my_list=None, available=True, playable_id=None):
"""
:type movie_id: str
:type name: str
Expand All @@ -83,8 +82,10 @@ def __init__(self, movie_id=None, name=None, description=None, year=None, poster
:type aired: str
:type my_list: bool
:type available: bool
:type playable_id: str
"""
self.movie_id = movie_id
self.playable_id = playable_id
self.name = name
self.description = description if description else ''
self.year = year
Expand All @@ -104,6 +105,33 @@ def __repr__(self):
return "%r" % self.__dict__


class Teaser:
""" Defines a teaser for a detail page of which we don't know yet if it's a Movie or a Program """

def __init__(self, detail_id=None, name=None, description=None, poster=None, thumb=None, fanart=None, my_list=None, available=True):
"""
:type detail_id: str
:type name: str
:type description: str
:type poster: str
:type thumb: str
:type fanart: str
:type my_list: bool
:type available: bool
"""
self.detail_id = detail_id
self.name = name
self.description = description if description else ''
self.poster = poster
self.thumb = thumb
self.fanart = fanart
self.my_list = my_list
self.available = available

def __repr__(self):
return "%r" % self.__dict__


class Program:
""" Defines a Program """

Expand Down
Loading