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

Add Kodi library support #815

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
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: 2 additions & 0 deletions addon.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down
36 changes: 36 additions & 0 deletions resources/language/resource.language.en_gb/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,42 @@ msgctxt "#30835"
msgid "De Warmste Week"
msgstr ""

msgctxt "#30840"
msgid "Kodi Library"
msgstr ""

msgctxt "#30841"
msgid "Indexing"
msgstr ""

msgctxt "#30843"
msgid "Add video locations to the Kodi Library… [COLOR gray](See README.md)[/COLOR]"
msgstr ""

msgctxt "#30845"
msgid "Index documentaries also"
msgstr ""

msgctxt "#30847"
msgid "Index music videos also"
msgstr ""

msgctxt "#30849"
msgid "Index only TV shows you follow"
msgstr ""

msgctxt "#30851"
msgid "Maintenance"
msgstr ""

msgctxt "#30853"
msgid "Refresh Library…"
msgstr ""

msgctxt "#30855"
msgid "Clean Library…"
msgstr ""

msgctxt "#30860"
msgid "Integration"
msgstr ""
Expand Down
36 changes: 36 additions & 0 deletions resources/language/resource.language.nl_nl/strings.po
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,42 @@ msgctxt "#30835"
msgid "De Warmste Week"
msgstr "De Warmste Week"

msgctxt "#30840"
msgid "Kodi Library"
msgstr "Kodi-bibliotheek"

msgctxt "#30841"
msgid "Indexing"
msgstr "Indexeren"

msgctxt "#30843"
msgid "Add video locations to the Kodi Library… [COLOR gray](See README.md)[/COLOR]"
msgstr "Videolocaties toevoegen aan de Kodi-bibliotheek… [COLOR gray](Zie README.md)[/COLOR]"

msgctxt "#30845"
msgid "Index documentaries also"
msgstr "Index ook documentaires"

msgctxt "#30847"
msgid "Index music videos also"
msgstr "Indexeer ook muziek video's"

msgctxt "#30849"
msgid "Index only TV shows you follow"
msgstr "Indexeer enkel tv-programma's die je volgt"

msgctxt "#30851"
msgid "Maintenance"
msgstr "Onderhoud"

msgctxt "#30853"
msgid "Refresh Library…"
msgstr "Verniew bibliotheek…"

msgctxt "#30855"
msgid "Clean Library…"
msgstr "Bibliotheek opkuisen…"

msgctxt "#30860"
msgid "Integration"
msgstr "Integratie"
Expand Down
40 changes: 39 additions & 1 deletion resources/lib/addon.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
except ImportError: # Python 2
from urllib import unquote_plus

from kodiutils import end_of_directory, execute_builtin, get_global_setting, localize, log_access, notification, ok_dialog, refresh_caches
from kodiutils import end_of_directory, execute_builtin, get_global_setting, jsonrpc, localize, log_access, notification, ok_dialog, refresh_caches
from utils import from_unicode, to_unicode

plugin = Plugin() # pylint: disable=invalid-name
Expand Down Expand Up @@ -337,6 +337,44 @@ 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('/library/configure')
def library_configure():
"""Configure the library integration"""
# There seems to be no way to add sources automatically
# → https://forum.kodi.tv/showthread.php?tid=228840
execute_builtin('ActivateWindow(Videos,sources://video/)')


@plugin.route('/library/update')
def library_update():
"""Refresh the library"""
jsonrpc(method='VideoLibrary.Scan')


@plugin.route('/library/clean')
def library_clean():
"""Clean the library"""
jsonrpc(method='VideoLibrary.Clean')


@plugin.route('/update/repos')
def update_repos():
"""Force an update of the repositories"""
Expand Down
10 changes: 9 additions & 1 deletion resources/lib/apihelper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
8 changes: 8 additions & 0 deletions resources/lib/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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),
Expand Down
18 changes: 18 additions & 0 deletions resources/lib/vrtplayer.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,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
Expand Down
10 changes: 10 additions & 0 deletions resources/settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@
<setting label="30834" type="bool" id="vrtnxt" default="true"/> <!-- VRT NXT -->
<setting label="30835" type="bool" id="de-warmste-week" default="false"/> <!-- De Warmste Week -->
</category>
<category label="30840"> <!-- Kodi Library -->
<setting label="30841" type="lsep"/> <!-- Indexing -->
<setting label="30843" type="action" action="RunPlugin(plugin://plugin.video.vrt.nu/library/configure)" option="close"/>
<setting label="30845" type="bool" id="library_include_docu" default="true"/>
<setting label="30847" type="bool" id="library_include_music" default="true"/>
<setting label="30849" type="bool" id="library_use_favorites" default="true"/>
<setting label="30851" type="lsep"/> <!-- Maintenance -->
<setting label="30853" type="action" action="RunPlugin(plugin://plugin.video.vrt.nu/library/update)"/>
<setting label="30855" type="action" action="RunPlugin(plugin://plugin.video.vrt.nu/library/clean)"/>
</category>
<category label="30860"> <!--Integration -->
<setting label="30861" type="lsep"/> <!-- Integration with other add-ons -->
<!-- YouTube -->
Expand Down
12 changes: 12 additions & 0 deletions tests/test_routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -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', ''])
Expand Down
5 changes: 4 additions & 1 deletion tests/userdata/addon_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down