Merge branch 'develop' into translations
This commit is contained in:
commit
0f292c2799
12 changed files with 156 additions and 19 deletions
|
@ -1,5 +1,5 @@
|
||||||
[![stable version](https://img.shields.io/badge/stable_version-1.8.0-blue.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect/bin/repository.plexkodiconnect/repository.plexkodiconnect-1.0.0.zip)
|
[![stable version](https://img.shields.io/badge/stable_version-1.8.1-blue.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect/bin/repository.plexkodiconnect/repository.plexkodiconnect-1.0.0.zip)
|
||||||
[![beta version](https://img.shields.io/badge/beta_version-1.8.0-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip)
|
[![beta version](https://img.shields.io/badge/beta_version-1.8.1-red.svg?maxAge=60&style=flat) ](https://dl.bintray.com/croneter/PlexKodiConnect_BETA/bin-BETA/repository.plexkodiconnectbeta/repository.plexkodiconnectbeta-1.0.0.zip)
|
||||||
|
|
||||||
[![Installation](https://img.shields.io/badge/wiki-installation-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/Installation)
|
[![Installation](https://img.shields.io/badge/wiki-installation-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/Installation)
|
||||||
[![FAQ](https://img.shields.io/badge/wiki-FAQ-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/faq)
|
[![FAQ](https://img.shields.io/badge/wiki-FAQ-brightgreen.svg?maxAge=60&style=flat)](https://github.com/croneter/PlexKodiConnect/wiki/faq)
|
||||||
|
|
10
addon.xml
10
addon.xml
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="1.8.0" provider-name="croneter">
|
<addon id="plugin.video.plexkodiconnect" name="PlexKodiConnect" version="1.8.1" provider-name="croneter">
|
||||||
<requires>
|
<requires>
|
||||||
<import addon="xbmc.python" version="2.1.0"/>
|
<import addon="xbmc.python" version="2.1.0"/>
|
||||||
<import addon="script.module.requests" version="2.3.0" />
|
<import addon="script.module.requests" version="2.3.0" />
|
||||||
|
@ -44,7 +44,13 @@
|
||||||
<disclaimer lang="nl_NL">Gebruik op eigen risico</disclaimer>
|
<disclaimer lang="nl_NL">Gebruik op eigen risico</disclaimer>
|
||||||
<disclaimer lang="zh_TW">使用風險由您自己承擔</disclaimer>
|
<disclaimer lang="zh_TW">使用風險由您自己承擔</disclaimer>
|
||||||
<disclaimer lang="es_ES">Usar a su propio riesgo</disclaimer>
|
<disclaimer lang="es_ES">Usar a su propio riesgo</disclaimer>
|
||||||
<news>version 1.8.0
|
<news>version 1.8.1:
|
||||||
|
- Fix library sync crash due to UnicodeDecodeError
|
||||||
|
- Fix fanart for collections
|
||||||
|
- Comply with themoviedb.org terms of use
|
||||||
|
- Add some translations
|
||||||
|
|
||||||
|
version 1.8.0
|
||||||
Featuring:
|
Featuring:
|
||||||
- Major music overhaul: Direct Paths should now work! Many thanks @Memesa for the pointers! Don't forget to reset your database
|
- Major music overhaul: Direct Paths should now work! Many thanks @Memesa for the pointers! Don't forget to reset your database
|
||||||
- Big transcoding overhaul
|
- Big transcoding overhaul
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
version 1.8.1:
|
||||||
|
- Fix library sync crash due to UnicodeDecodeError
|
||||||
|
- Fix fanart for collections
|
||||||
|
- Comply with themoviedb.org terms of use
|
||||||
|
- Add some translations
|
||||||
|
|
||||||
version 1.8.0
|
version 1.8.0
|
||||||
Featuring:
|
Featuring:
|
||||||
- Major music overhaul: Direct Paths should now work! Many thanks @Memesa for the pointers! Don't forget to reset your database
|
- Major music overhaul: Direct Paths should now work! Many thanks @Memesa for the pointers! Don't forget to reset your database
|
||||||
|
|
|
@ -1943,4 +1943,14 @@ msgstr ""
|
||||||
# Shown once on first installation to comply with the terms of use of themoviedb.org
|
# Shown once on first installation to comply with the terms of use of themoviedb.org
|
||||||
msgctxt "#39717"
|
msgctxt "#39717"
|
||||||
msgid "PKC uses free additional artwork from www.themoviedb.org. Many thanks!"
|
msgid "PKC uses free additional artwork from www.themoviedb.org. Many thanks!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
# Shown during very first PKC setup only
|
||||||
|
msgctxt "#39718"
|
||||||
|
msgid "Do you want to replace your custom user ratings with an indicator of how many versions of a media item you posses?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
# In PKC Settings under Sync
|
||||||
|
msgctxt "#39719"
|
||||||
|
msgid "Replace user ratings with number of media versions"
|
||||||
|
msgstr ""
|
||||||
|
|
|
@ -1288,10 +1288,17 @@ class API():
|
||||||
except (KeyError, ValueError):
|
except (KeyError, ValueError):
|
||||||
lastPlayedDate = None
|
lastPlayedDate = None
|
||||||
|
|
||||||
try:
|
if state.INDICATE_MEDIA_VERSIONS is True:
|
||||||
userrating = int(float(item['userRating']))
|
|
||||||
except (KeyError, ValueError):
|
|
||||||
userrating = 0
|
userrating = 0
|
||||||
|
for entry in self.item.findall('./Media'):
|
||||||
|
userrating += 1
|
||||||
|
# Don't show a value of '1'
|
||||||
|
userrating = 0 if userrating == 1 else userrating
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
userrating = int(float(item['userRating']))
|
||||||
|
except (KeyError, ValueError):
|
||||||
|
userrating = 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
rating = float(item['audienceRating'])
|
rating = float(item['audienceRating'])
|
||||||
|
@ -1881,7 +1888,8 @@ class API():
|
||||||
|
|
||||||
If not found in item's Plex metadata, check themovidedb.org
|
If not found in item's Plex metadata, check themovidedb.org
|
||||||
|
|
||||||
collection=True will try to return the collection's ID
|
collection=True will try to return the three-tuple:
|
||||||
|
collection ID, poster-path, background-path
|
||||||
|
|
||||||
None is returned if unsuccessful
|
None is returned if unsuccessful
|
||||||
"""
|
"""
|
||||||
|
@ -1900,7 +1908,8 @@ class API():
|
||||||
log.info('Plex did not provide ID for IMDB or TVDB. Start '
|
log.info('Plex did not provide ID for IMDB or TVDB. Start '
|
||||||
'lookup process')
|
'lookup process')
|
||||||
else:
|
else:
|
||||||
log.info('Start movie set/collection lookup on themoviedb')
|
log.info('Start movie set/collection lookup on themoviedb using %s'
|
||||||
|
% item.get('title', ''))
|
||||||
|
|
||||||
apiKey = settings('themoviedbAPIKey')
|
apiKey = settings('themoviedbAPIKey')
|
||||||
if media_type == v.PLEX_TYPE_SHOW:
|
if media_type == v.PLEX_TYPE_SHOW:
|
||||||
|
@ -1909,7 +1918,7 @@ class API():
|
||||||
# if the title has the year in remove it as tmdb cannot deal with it...
|
# if the title has the year in remove it as tmdb cannot deal with it...
|
||||||
# replace e.g. 'The Americans (2015)' with 'The Americans'
|
# replace e.g. 'The Americans (2015)' with 'The Americans'
|
||||||
title = sub(r'\s*\(\d{4}\)$', '', title, count=1)
|
title = sub(r'\s*\(\d{4}\)$', '', title, count=1)
|
||||||
url = 'http://api.themoviedb.org/3/search/%s' % media_type
|
url = 'https://api.themoviedb.org/3/search/%s' % media_type
|
||||||
parameters = {
|
parameters = {
|
||||||
'api_key': apiKey,
|
'api_key': apiKey,
|
||||||
'language': v.KODILANGUAGE,
|
'language': v.KODILANGUAGE,
|
||||||
|
@ -2001,10 +2010,10 @@ class API():
|
||||||
for language in [v.KODILANGUAGE, "en"]:
|
for language in [v.KODILANGUAGE, "en"]:
|
||||||
parameters['language'] = language
|
parameters['language'] = language
|
||||||
if media_type == "movie":
|
if media_type == "movie":
|
||||||
url = 'http://api.themoviedb.org/3/movie/%s' % tmdbId
|
url = 'https://api.themoviedb.org/3/movie/%s' % tmdbId
|
||||||
parameters['append_to_response'] = 'videos'
|
parameters['append_to_response'] = 'videos'
|
||||||
elif media_type == "tv":
|
elif media_type == "tv":
|
||||||
url = 'http://api.themoviedb.org/3/tv/%s' % tmdbId
|
url = 'https://api.themoviedb.org/3/tv/%s' % tmdbId
|
||||||
parameters['append_to_response'] = 'external_ids,videos'
|
parameters['append_to_response'] = 'external_ids,videos'
|
||||||
data = DownloadUtils().downloadUrl(
|
data = DownloadUtils().downloadUrl(
|
||||||
url,
|
url,
|
||||||
|
@ -2025,9 +2034,28 @@ class API():
|
||||||
mediaId = str(data["external_ids"].get("tvdb_id"))
|
mediaId = str(data["external_ids"].get("tvdb_id"))
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
if data.get("belongs_to_collection") is not None:
|
if data.get("belongs_to_collection") is None:
|
||||||
mediaId = str(data.get("belongs_to_collection").get("id"))
|
continue
|
||||||
log.debug('Retrieved collections tmdb id %s' % mediaId)
|
mediaId = str(data.get("belongs_to_collection").get("id"))
|
||||||
|
log.debug('Retrieved collections tmdb id %s for %s'
|
||||||
|
% (mediaId, title))
|
||||||
|
url = 'https://api.themoviedb.org/3/collection/%s' % mediaId
|
||||||
|
data = DownloadUtils().downloadUrl(
|
||||||
|
url,
|
||||||
|
authenticate=False,
|
||||||
|
parameters=parameters,
|
||||||
|
timeout=7)
|
||||||
|
try:
|
||||||
|
data.get('poster_path')
|
||||||
|
except AttributeError:
|
||||||
|
log.info('Could not find TheMovieDB poster paths for %s in'
|
||||||
|
'the language %s' % (title, language))
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
poster = 'https://image.tmdb.org/t/p/original%s' % data.get('poster_path')
|
||||||
|
background = 'https://image.tmdb.org/t/p/original%s' % data.get('backdrop_path')
|
||||||
|
mediaId = mediaId, poster, background
|
||||||
|
break
|
||||||
return mediaId
|
return mediaId
|
||||||
|
|
||||||
def getFanartTVArt(self, mediaId, allartworks, setInfo=False):
|
def getFanartTVArt(self, mediaId, allartworks, setInfo=False):
|
||||||
|
@ -2158,7 +2186,18 @@ class API():
|
||||||
# fanart tv only for movie or tv show
|
# fanart tv only for movie or tv show
|
||||||
externalId = self.getExternalItemId(collection=True)
|
externalId = self.getExternalItemId(collection=True)
|
||||||
if externalId is not None:
|
if externalId is not None:
|
||||||
|
try:
|
||||||
|
externalId, poster, background = externalId
|
||||||
|
except TypeError:
|
||||||
|
poster, background = None, None
|
||||||
|
if poster is not None:
|
||||||
|
allartworks['Primary'] = poster
|
||||||
|
if background is not None:
|
||||||
|
allartworks['Backdrop'].append(background)
|
||||||
allartworks = self.getFanartTVArt(externalId, allartworks, True)
|
allartworks = self.getFanartTVArt(externalId, allartworks, True)
|
||||||
|
else:
|
||||||
|
log.info('Did not find a set/collection ID on TheMovieDB using %s.'
|
||||||
|
' Artwork will be missing.' % self.getTitle()[0])
|
||||||
return allartworks
|
return allartworks
|
||||||
|
|
||||||
def shouldStream(self):
|
def shouldStream(self):
|
||||||
|
|
|
@ -12,6 +12,7 @@ from plexbmchelper import listener, plexgdm, subscribers, functions, \
|
||||||
httppersist, plexsettings
|
httppersist, plexsettings
|
||||||
from PlexFunctions import ParseContainerKey, GetPlexMetadata
|
from PlexFunctions import ParseContainerKey, GetPlexMetadata
|
||||||
from PlexAPI import API
|
from PlexAPI import API
|
||||||
|
from playlist_func import get_pms_playqueue, get_plextype_from_xml
|
||||||
import player
|
import player
|
||||||
import variables as v
|
import variables as v
|
||||||
import state
|
import state
|
||||||
|
@ -149,6 +150,26 @@ class PlexCompanion(Thread):
|
||||||
offset=data.get('offset'))
|
offset=data.get('offset'))
|
||||||
playqueue.plex_transient_token = token
|
playqueue.plex_transient_token = token
|
||||||
|
|
||||||
|
elif task['action'] == 'refreshPlayQueue':
|
||||||
|
# example data: {'playQueueID': '8475', 'commandID': '11'}
|
||||||
|
xml = get_pms_playqueue(data['playQueueID'])
|
||||||
|
if xml is None:
|
||||||
|
return
|
||||||
|
if len(xml) == 0:
|
||||||
|
log.debug('Empty playqueue received - clearing playqueue')
|
||||||
|
plex_type = get_plextype_from_xml(xml)
|
||||||
|
if plex_type is None:
|
||||||
|
return
|
||||||
|
playqueue = self.mgr.playqueue.get_playqueue_from_type(
|
||||||
|
v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[plex_type])
|
||||||
|
playqueue.clear()
|
||||||
|
return
|
||||||
|
playqueue = self.mgr.playqueue.get_playqueue_from_type(
|
||||||
|
v.KODI_PLAYLIST_TYPE_FROM_PLEX_TYPE[xml[0].attrib['type']])
|
||||||
|
self.mgr.playqueue.update_playqueue_from_PMS(
|
||||||
|
playqueue,
|
||||||
|
data['playQueueID'])
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
# Ensure that sockets will be closed no matter what
|
# Ensure that sockets will be closed no matter what
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -110,11 +110,19 @@ def process_command(request_path, params, queue=None):
|
||||||
'data': params
|
'data': params
|
||||||
})
|
})
|
||||||
|
|
||||||
|
elif request_path == 'player/playback/refreshPlayQueue':
|
||||||
|
queue.put({
|
||||||
|
'action': 'refreshPlayQueue',
|
||||||
|
'data': params
|
||||||
|
})
|
||||||
|
|
||||||
elif request_path == "player/playback/setParameters":
|
elif request_path == "player/playback/setParameters":
|
||||||
if 'volume' in params:
|
if 'volume' in params:
|
||||||
volume = int(params['volume'])
|
volume = int(params['volume'])
|
||||||
log.debug("Adjusting the volume to %s" % volume)
|
log.debug("Adjusting the volume to %s" % volume)
|
||||||
JSONRPC('Application.SetVolume').execute({"volume": volume})
|
JSONRPC('Application.SetVolume').execute({"volume": volume})
|
||||||
|
else:
|
||||||
|
log.error('Unknown parameters: %s' % params)
|
||||||
|
|
||||||
elif request_path == "player/playback/play":
|
elif request_path == "player/playback/play":
|
||||||
for playerid in getPlayerIds():
|
for playerid in getPlayerIds():
|
||||||
|
|
|
@ -488,10 +488,16 @@ class InitialSetup():
|
||||||
if dialog.yesno(heading=lang(29999), line1=lang(39061)):
|
if dialog.yesno(heading=lang(29999), line1=lang(39061)):
|
||||||
log.debug("User opted to use FanArtTV")
|
log.debug("User opted to use FanArtTV")
|
||||||
settings('FanartTV', value="true")
|
settings('FanartTV', value="true")
|
||||||
|
# Do you want to replace your custom user ratings with an indicator of
|
||||||
|
# how many versions of a media item you posses?
|
||||||
|
if dialog.yesno(heading=lang(29999), line1=lang(39718)):
|
||||||
|
log.debug("User opted to replace user ratings with version number")
|
||||||
|
settings('indicate_media_versions', value="true")
|
||||||
|
|
||||||
# If you use several Plex libraries of one kind, e.g. "Kids Movies" and
|
# If you use several Plex libraries of one kind, e.g. "Kids Movies" and
|
||||||
# "Parents Movies", be sure to check https://goo.gl/JFtQV9
|
# "Parents Movies", be sure to check https://goo.gl/JFtQV9
|
||||||
dialog.ok(heading=lang(29999), line1=lang(39076))
|
dialog.ok(heading=lang(29999), line1=lang(39076))
|
||||||
|
|
||||||
# Need to tell about our image source for collections: themoviedb.org
|
# Need to tell about our image source for collections: themoviedb.org
|
||||||
dialog.ok(heading=lang(29999), line1=lang(39717))
|
dialog.ok(heading=lang(29999), line1=lang(39717))
|
||||||
# Make sure that we only ask these questions upon first installation
|
# Make sure that we only ask these questions upon first installation
|
||||||
|
|
|
@ -1,16 +1,19 @@
|
||||||
import logging
|
import logging
|
||||||
from urllib import quote
|
from urllib import quote
|
||||||
from urlparse import parse_qsl, urlsplit
|
from urlparse import parse_qsl, urlsplit
|
||||||
|
from re import compile as re_compile
|
||||||
|
|
||||||
import plexdb_functions as plexdb
|
import plexdb_functions as plexdb
|
||||||
from downloadutils import DownloadUtils as DU
|
from downloadutils import DownloadUtils as DU
|
||||||
from utils import JSONRPC, tryEncode, escape_html
|
from utils import JSONRPC, tryEncode, escape_html
|
||||||
from PlexAPI import API
|
from PlexAPI import API
|
||||||
|
from PlexFunctions import GetPlexMetadata
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
log = logging.getLogger("PLEX."+__name__)
|
log = logging.getLogger("PLEX."+__name__)
|
||||||
|
|
||||||
|
REGEX = re_compile(r'''metadata%2F(\d+)''')
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
# kodi_item dict:
|
# kodi_item dict:
|
||||||
|
@ -63,9 +66,6 @@ class Playlist_Object_Baseclase(object):
|
||||||
self.plex_transient_token = None
|
self.plex_transient_token = None
|
||||||
log.debug('Playlist cleared: %s' % self)
|
log.debug('Playlist cleared: %s' % self)
|
||||||
|
|
||||||
def log_Kodi_playlist(self):
|
|
||||||
log.debug('Current Kodi playlist: %s' % get_kodi_playlist_items(self))
|
|
||||||
|
|
||||||
|
|
||||||
class Playlist_Object(Playlist_Object_Baseclase):
|
class Playlist_Object(Playlist_Object_Baseclase):
|
||||||
kind = 'playList'
|
kind = 'playList'
|
||||||
|
@ -566,3 +566,39 @@ def remove_from_Kodi_playlist(playlist, pos):
|
||||||
del playlist.items[pos]
|
del playlist.items[pos]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
log.error('Cannot delete position %s for %s' % (pos, playlist))
|
log.error('Cannot delete position %s for %s' % (pos, playlist))
|
||||||
|
|
||||||
|
|
||||||
|
def get_pms_playqueue(playqueue_id):
|
||||||
|
"""
|
||||||
|
Returns the Plex playqueue as an etree XML or None if unsuccessful
|
||||||
|
"""
|
||||||
|
xml = DU().downloadUrl(
|
||||||
|
"{server}/playQueues/%s" % playqueue_id,
|
||||||
|
headerOptions={'Accept': 'application/xml'})
|
||||||
|
try:
|
||||||
|
xml.attrib
|
||||||
|
except AttributeError:
|
||||||
|
log.error('Could not download Plex playqueue %s' % playqueue_id)
|
||||||
|
xml = None
|
||||||
|
return xml
|
||||||
|
|
||||||
|
|
||||||
|
def get_plextype_from_xml(xml):
|
||||||
|
"""
|
||||||
|
Needed if PMS returns an empty playqueue. Will get the Plex type from the
|
||||||
|
empty playlist playQueueSourceURI. Feed with (empty) etree xml
|
||||||
|
|
||||||
|
returns None if unsuccessful
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
plex_id = REGEX.findall(xml.attrib['playQueueSourceURI'])[0]
|
||||||
|
except IndexError:
|
||||||
|
log.error('Could not get plex_id from xml: %s' % xml.attrib)
|
||||||
|
return
|
||||||
|
new_xml = GetPlexMetadata(plex_id)
|
||||||
|
try:
|
||||||
|
new_xml[0].attrib
|
||||||
|
except (TypeError, IndexError, AttributeError):
|
||||||
|
log.error('Could not get plex metadata for plex id %s' % plex_id)
|
||||||
|
return
|
||||||
|
return new_xml[0].attrib.get('type')
|
||||||
|
|
|
@ -22,6 +22,8 @@ RESTRICTED_USER = False
|
||||||
# Direct Paths (True) or Addon Paths (False)? Along with
|
# Direct Paths (True) or Addon Paths (False)? Along with
|
||||||
# window('useDirectPaths')
|
# window('useDirectPaths')
|
||||||
DIRECT_PATHS = False
|
DIRECT_PATHS = False
|
||||||
|
# Shall we replace custom user ratings with the number of versions available?
|
||||||
|
INDICATE_MEDIA_VERSIONS = False
|
||||||
|
|
||||||
# Along with window('plex_authenticated')
|
# Along with window('plex_authenticated')
|
||||||
AUTHENTICATED = False
|
AUTHENTICATED = False
|
||||||
|
|
|
@ -165,6 +165,8 @@ class UserClient(threading.Thread):
|
||||||
if settings('useDirectPaths') == "1" else 'false')
|
if settings('useDirectPaths') == "1" else 'false')
|
||||||
state.DIRECT_PATHS = True if settings('useDirectPaths') == "1" \
|
state.DIRECT_PATHS = True if settings('useDirectPaths') == "1" \
|
||||||
else False
|
else False
|
||||||
|
state.INDICATE_MEDIA_VERSIONS = True \
|
||||||
|
if settings('indicate_media_versions') == "true" else False
|
||||||
window('plex_force_transcode_pix', value='true'
|
window('plex_force_transcode_pix', value='true'
|
||||||
if settings('force_transcode_pix') == "1" else 'false')
|
if settings('force_transcode_pix') == "1" else 'false')
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
<setting id="dbSyncScreensaver" type="bool" label="39062" default="false" /><!--Sync when screensaver is deactivated-->
|
<setting id="dbSyncScreensaver" type="bool" label="39062" default="false" /><!--Sync when screensaver is deactivated-->
|
||||||
|
|
||||||
<setting type="lsep" label="30538" /><!-- Complete Re-Sync necessary -->
|
<setting type="lsep" label="30538" /><!-- Complete Re-Sync necessary -->
|
||||||
|
<setting id="indicate_media_versions" type="bool" label="39719" default="false" /><!-- Replace user ratings with number of versions -->
|
||||||
<setting id="enableMusic" type="bool" label="30509" default="true" />
|
<setting id="enableMusic" type="bool" label="30509" default="true" />
|
||||||
<setting id="useDirectPaths" type="enum" label="30511" values="Addon(Default)|Native(Direct paths)" default="0" visible="true"/> <!-- Playback mode -->
|
<setting id="useDirectPaths" type="enum" label="30511" values="Addon(Default)|Native(Direct paths)" default="0" visible="true"/> <!-- Playback mode -->
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue