From 24217a69aa392b8511b59472200781c90635de57 Mon Sep 17 00:00:00 2001
From: Dag Wieers <dag@wieers.com>
Date: Mon, 28 Sep 2020 01:15:56 +0200
Subject: [PATCH] Add Kodi library support

This adds support for adding VRT NU as a Kodi library source.

To use this, add the following Video sources to your Kodi:

- VRT NU - Movies
  - location: plugin://plugin.video.vrt.nu/library/movies
  - type: Movies
  - provider: Local Information only
- VRT NU - TV shows
  - location: plugin://plugin.video.vrt.nu/library/tvshows
  - type: TV shows
  - provider: Local Information only

Then update your library to get VRT NU Movies and TV shows to show up in
the standard Kodi library.
---
 addon.xml                          |  2 ++
 resources/lib/addon.py             | 18 ++++++++++++++++++
 resources/lib/apihelper.py         | 10 +++++++++-
 resources/lib/metadata.py          |  8 ++++++++
 resources/lib/vrtplayer.py         | 18 ++++++++++++++++++
 tests/test_routing.py              | 12 ++++++++++++
 tests/userdata/addon_settings.json |  5 ++++-
 7 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/addon.xml b/addon.xml
index f4cf351ef..4bc918c2d 100644
--- a/addon.xml
+++ b/addon.xml
@@ -10,6 +10,8 @@
   </requires>
   <extension point="xbmc.python.pluginsource" library="resources/lib/addon_entry.py">
     <provides>video</provides>
+    <medialibraryscanpath content="movies">library/movies</medialibraryscanpath>
+    <medialibraryscanpath content="tvshows">library/tvshows</medialibraryscanpath>
   </extension>
   <extension point="xbmc.service" library="resources/lib/service_entry.py"/>
   <extension point="xbmc.addon.metadata">
diff --git a/resources/lib/addon.py b/resources/lib/addon.py
index dade1256f..8a4e78de0 100644
--- a/resources/lib/addon.py
+++ b/resources/lib/addon.py
@@ -337,6 +337,24 @@ def iptv_epg():
     IPTVManager(port).send_epg()
 
 
+@plugin.route('/library/movies')
+def library_movies():
+    """Show movie listitems to be used as a Kodi source"""
+    from vrtplayer import VRTPlayer
+    VRTPlayer().show_library_movies()
+
+
+@plugin.route('/library/tvshows')
+@plugin.route('/library/tvshows/<program>')
+def library_tvshows(program=None):
+    """Show tvshow listitems to be used as a Kodi source"""
+    from vrtplayer import VRTPlayer
+    if program:
+        VRTPlayer().show_episodes_menu(program=program, season='allseasons')
+    else:
+        VRTPlayer().show_library_tvshows()
+
+
 @plugin.route('/update/repos')
 def update_repos():
     """Force an update of the repositories"""
diff --git a/resources/lib/apihelper.py b/resources/lib/apihelper.py
index 6412f1231..d480158b9 100644
--- a/resources/lib/apihelper.py
+++ b/resources/lib/apihelper.py
@@ -78,15 +78,23 @@ def list_tvshows(self, category=None, channel=None, feature=None, use_favorites=
 
     def tvshow_to_listitem(self, tvshow, program, cache_file):
         """Return a ListItem based on a Suggests API result"""
+        from addon import plugin
+
         label = self._metadata.get_label(tvshow)
 
         if program:
             context_menu, favorite_marker, _ = self._metadata.get_context_menu(tvshow, program, cache_file)
             label += favorite_marker
 
+        # Support Kodi library source scanning
+        if plugin.path.startswith('/library'):
+            path = url_for('library_tvshows', program=program)
+        else:
+            path = url_for('programs', program=program)
+
         return TitleItem(
             label=label,
-            path=url_for('programs', program=program),
+            path=path,
             art_dict=self._metadata.get_art(tvshow),
             info_dict=self._metadata.get_info_labels(tvshow),
             context_menu=context_menu,
diff --git a/resources/lib/metadata.py b/resources/lib/metadata.py
index deb879a15..af8ab8847 100644
--- a/resources/lib/metadata.py
+++ b/resources/lib/metadata.py
@@ -214,6 +214,13 @@ def get_properties(self, api_data):
             if year:
                 properties['year'] = year
 
+        # Poor man's implementation, use thumbnail and episode_count to detect change
+        from hashlib import md5
+        message = md5()
+        message.update(api_data.get('thumbnail', '').encode('ascii'))
+        message.update(str(api_data.get('episode_count', 0)).encode('ascii'))
+        properties['hash'] = message.hexdigest().upper()
+
         return properties
 
     @staticmethod
@@ -661,6 +668,7 @@ def get_info_labels(self, api_data, season=False, date=None, channel=None):
         # VRT NU Suggest API
         if api_data.get('type') == 'program':
             info_labels = dict(
+                title=self.get_tvshowtitle(api_data),
                 tvshowtitle=self.get_tvshowtitle(api_data),
                 plot=self.get_plot(api_data),
                 mediatype=self.get_mediatype(api_data, season=season),
diff --git a/resources/lib/vrtplayer.py b/resources/lib/vrtplayer.py
index 5a29eb81c..795a31620 100644
--- a/resources/lib/vrtplayer.py
+++ b/resources/lib/vrtplayer.py
@@ -192,6 +192,24 @@ def show_favorites_music_menu(self):
         episode_items, sort, ascending, content = self._apihelper.list_episodes(category='muziek', season='allseasons', programtype='oneoff')
         show_listing(episode_items, category=30046, sort=sort, ascending=ascending, content=content, cache=False)
 
+    def show_library_movies(self):
+        """Show movie listitems to be used as a Kodi source"""
+        docu_items = []
+        music_items = []
+        if get_setting_bool('library_include_docu', default=True):
+            docu_items, _, _, _ = self._apihelper.list_episodes(category='docu', season='allseasons', programtype='oneoff')
+        if get_setting_bool('library_include_music', default=True):
+            music_items, _, _, _ = self._apihelper.list_episodes(category='muziek', season='allseasons', programtype='oneoff')
+        movie_items, sort, _, _ = self._apihelper.list_episodes(category='films', season='allseasons', programtype='oneoff')
+        show_listing(movie_items + docu_items + music_items, sort=sort, content='movies')
+
+    def show_library_tvshows(self):
+        """Show tvshow listitems to be used as a Kodi source"""
+        self._favorites.refresh(ttl=ttl('direct'))
+        self._resumepoints.refresh(ttl=ttl('direct'))
+        tvshow_items = self._apihelper.list_tvshows(use_favorites=get_setting_bool('library_use_favorites', default=True))
+        show_listing(tvshow_items, sort='label', content='tvshows')
+
     def show_tvshow_menu(self, use_favorites=False):
         """The VRT NU add-on 'All programs' listing menu"""
         # My favorites menus may need more up-to-date favorites
diff --git a/tests/test_routing.py b/tests/test_routing.py
index 8410a5c45..bfbc706ab 100644
--- a/tests/test_routing.py
+++ b/tests/test_routing.py
@@ -271,6 +271,18 @@ def test_play_whatson_id(self):
         addon.run(['plugin://plugin.video.vrt.nu/play/whatson/490431755527', '0', ''])
         self.assertEqual(plugin.url_for(addon.play_whatson_id, whatson_id='490431755527'), 'plugin://plugin.video.vrt.nu/play/whatson/490431755527')
 
+    def test_library_movies(self):
+        """Library Movies scan: /library/movies"""
+        addon.run(['plugin://plugin.video.vrt.nu/library/movies', '0', ''])
+        self.assertEqual(plugin.url_for(addon.library_movies), 'plugin://plugin.video.vrt.nu/library/movies')
+
+    def test_library_tvshows(self):
+        """Library TV shows scan: /library/tvshows"""
+        addon.run(['plugin://plugin.video.vrt.nu/library/tvshows', '0', ''])
+        self.assertEqual(plugin.url_for(addon.library_tvshows), 'plugin://plugin.video.vrt.nu/library/tvshows')
+        addon.run(['plugin://plugin.video.vrt.nu/library/tvshows/het-journaal', '0', ''])
+        self.assertEqual(plugin.url_for(addon.library_tvshows, program='het-journaal'), 'plugin://plugin.video.vrt.nu/library/tvshows/het-journaal')
+
     def test_update_repos(self):
         """Update repositories: /update/repos"""
         addon.run(['plugin://plugin.video.vrt.nu/update/repos', '0', ''])
diff --git a/tests/userdata/addon_settings.json b/tests/userdata/addon_settings.json
index 4e0b4b201..769b46fff 100644
--- a/tests/userdata/addon_settings.json
+++ b/tests/userdata/addon_settings.json
@@ -16,10 +16,13 @@
         "een": "true",
         "httpcachettldirect": "1",
         "httpcachettlindirect": "5",
+        "itemsperpage": "20",
         "ketnet": "false",
         "ketnet-jr": "false",
         "klara": "true",
-        "itemsperpage": "20",
+        "library_include_docu": "true",
+        "library_include_music": "true",
+        "library_use_favorites": "true",
         "max_bandwidth": "10000000",
         "max_log_level": "3",
         "mnm": "true",