This commit is contained in:
angelblue05 2016-09-10 06:15:58 -05:00 committed by GitHub
parent cd06049e86
commit b34007f727
13 changed files with 640 additions and 732 deletions

View file

@ -109,7 +109,7 @@ class ContextMenu(object):
def _select_menu(self):
# Display select dialog
userdata = self.api.getUserData()
userdata = self.api.get_userdata()
options = []
if userdata['Favorite']:
@ -178,7 +178,7 @@ class ContextMenu(object):
new_value = 5
if settings('enableUpdateSongRating') == "true":
musicutils.updateRatingToFile(new_value, self.api.getFilePath())
musicutils.updateRatingToFile(new_value, self.api.get_file_path())
query = "UPDATE song SET rating = ? WHERE idSong = ?"
cursor.execute(query, (new_value, self.kodi_id,))

View file

@ -70,7 +70,7 @@ class Main(object):
elif mode == 'texturecache':
import artwork
artwork.Artwork().fullTextureCacheSync()
artwork.Artwork().texture_cache_sync()
else:
entrypoint.doMainListing()
@ -136,7 +136,7 @@ class Main(object):
dialog(type_="ok",
heading="{emby}",
line1=lang(33034))
log.warn("Not connected to the emby server.")
log.warn("Not connected to the emby server")
elif window('emby_dbScan') != "true":
import librarysync
@ -149,7 +149,7 @@ class Main(object):
else:
library_sync.fullSync(repair=True)
else:
log.warn("Database scan is already running.")
log.warn("Database scan is already running")
if __name__ == "__main__":

View file

@ -14,45 +14,42 @@ log = logging.getLogger("EMBY."+__name__)
##################################################################################################
class API():
class API(object):
def __init__(self, item):
# item is the api response
self.item = item
def getUserData(self):
def get_userdata(self):
# Default
favorite = False
likes = None
playcount = None
played = False
lastPlayedDate = None
last_played = None
resume = 0
userrating = 0
user_rating = 0
try:
userdata = self.item['UserData']
except KeyError: # No userdata found.
pass
else:
favorite = userdata['IsFavorite']
likes = userdata.get('Likes')
# Userrating is based on likes and favourite
if favorite:
userrating = 5
user_rating = 5
elif likes:
userrating = 3
elif likes == False:
userrating = 0
user_rating = 3
elif likes is False:
user_rating = 0
else:
userrating = 1
user_rating = 1
lastPlayedDate = userdata.get('LastPlayedDate')
if lastPlayedDate:
lastPlayedDate = lastPlayedDate.split('.')[0].replace('T', " ")
last_played = userdata.get('LastPlayedDate')
if last_played:
last_played = last_played.split('.')[0].replace('T', " ")
if userdata['Played']:
# Playcount is tied to the watch status
@ -61,12 +58,12 @@ class API():
if playcount == 0:
playcount = 1
if lastPlayedDate is None:
lastPlayedDate = self.getDateCreated()
if last_played is None:
last_played = self.get_date_created()
playbackPosition = userdata.get('PlaybackPositionTicks')
if playbackPosition:
resume = playbackPosition / 10000000.0
playback_position = userdata.get('PlaybackPositionTicks')
if playback_position:
resume = playback_position / 10000000.0
return {
@ -74,12 +71,12 @@ class API():
'Likes': likes,
'PlayCount': playcount,
'Played': played,
'LastPlayedDate': lastPlayedDate,
'LastPlayedDate': last_played,
'Resume': resume,
'UserRating': userrating
'UserRating': user_rating
}
def getPeople(self):
def get_people(self):
# Process People
director = []
writer = []
@ -87,21 +84,19 @@ class API():
try:
people = self.item['People']
except KeyError:
pass
else:
for person in people:
type = person['Type']
type_ = person['Type']
name = person['Name']
if "Director" in type:
if type_ == 'Director':
director.append(name)
elif "Actor" in type:
elif type_ == 'Actor':
cast.append(name)
elif type in ("Writing", "Writer"):
elif type_ in ('Writing', 'Writer'):
writer.append(name)
return {
@ -111,101 +106,115 @@ class API():
'Cast': cast
}
def getMediaStreams(self):
videotracks = []
audiotracks = []
subtitlelanguages = []
def get_media_streams(self):
video_tracks = []
audio_tracks = []
subtitle_languages = []
try:
media_streams = self.item['MediaSources'][0]['MediaStreams']
except KeyError:
if not self.item.get("MediaStreams"): return None
if not self.item.get("MediaStreams"):
return None
media_streams = self.item['MediaStreams']
for media_stream in media_streams:
# Sort through Video, Audio, Subtitle
stream_type = media_stream['Type']
codec = media_stream.get('Codec', "").lower()
profile = media_stream.get('Profile', "").lower()
if stream_type == "Video":
# Height, Width, Codec, AspectRatio, AspectFloat, 3D
track = {
'codec': codec,
'height': media_stream.get('Height'),
'width': media_stream.get('Width'),
'video3DFormat': self.item.get('Video3DFormat'),
'aspect': 1.85
}
try:
container = self.item['MediaSources'][0]['Container'].lower()
except:
container = ""
# Sort codec vs container/profile
if "msmpeg4" in codec:
track['codec'] = "divx"
elif "mpeg4" in codec:
if "simple profile" in profile or not profile:
track['codec'] = "xvid"
elif "h264" in codec:
if container in ("mp4", "mov", "m4v"):
track['codec'] = "avc1"
# Aspect ratio
if self.item.get('AspectRatio'):
# Metadata AR
aspect = self.item['AspectRatio']
else: # File AR
aspect = media_stream.get('AspectRatio', "0")
try:
aspectwidth, aspectheight = aspect.split(':')
track['aspect'] = round(float(aspectwidth) / float(aspectheight), 6)
except (ValueError, ZeroDivisionError):
width = track.get('width')
height = track.get('height')
if width and height:
track['aspect'] = round(float(width / height), 6)
else:
track['aspect'] = 1.85
if self.item.get("RunTimeTicks"):
track['duration'] = self.item.get("RunTimeTicks") / 10000000.0
videotracks.append(track)
self._video_stream(video_tracks, media_stream)
elif stream_type == "Audio":
# Codec, Channels, language
track = {
'codec': codec,
'channels': media_stream.get('Channels'),
'language': media_stream.get('Language')
}
if "dca" in codec and "dts-hd ma" in profile:
track['codec'] = "dtshd_ma"
audiotracks.append(track)
self._audio_stream(audio_tracks, media_stream)
elif stream_type == "Subtitle":
# Language
subtitlelanguages.append(media_stream.get('Language', "Unknown"))
subtitle_languages.append(media_stream.get('Language', "Unknown"))
return {
'video': videotracks,
'audio': audiotracks,
'subtitle': subtitlelanguages
'video': video_tracks,
'audio': audio_tracks,
'subtitle': subtitle_languages
}
def getRuntime(self):
def _video_stream(self, video_tracks, stream):
codec = stream.get('Codec', "").lower()
profile = stream.get('Profile', "").lower()
# Height, Width, Codec, AspectRatio, AspectFloat, 3D
track = {
'codec': codec,
'height': stream.get('Height'),
'width': stream.get('Width'),
'video3DFormat': self.item.get('Video3DFormat'),
'aspect': 1.85
}
try:
container = self.item['MediaSources'][0]['Container'].lower()
except Exception:
container = ""
# Sort codec vs container/profile
if "msmpeg4" in codec:
track['codec'] = "divx"
elif "mpeg4" in codec:
if "simple profile" in profile or not profile:
track['codec'] = "xvid"
elif "h264" in codec:
if container in ("mp4", "mov", "m4v"):
track['codec'] = "avc1"
# Aspect ratio
if 'AspectRatio' in self.item:
# Metadata AR
aspect = self.item['AspectRatio']
else: # File AR
aspect = stream.get('AspectRatio', "0")
try:
aspect_width, aspect_height = aspect.split(':')
track['aspect'] = round(float(aspect_width) / float(aspect_height), 6)
except (ValueError, ZeroDivisionError):
width = track.get('width')
height = track.get('height')
if width and height:
track['aspect'] = round(float(width / height), 6)
else:
track['aspect'] = 1.85
if 'RunTimeTicks' in self.item:
track['duration'] = self.get_runtime()
video_tracks.append(track)
def _audio_stream(self, audio_tracks, stream):
codec = stream.get('Codec', "").lower()
profile = stream.get('Profile', "").lower()
# Codec, Channels, language
track = {
'codec': codec,
'channels': stream.get('Channels'),
'language': stream.get('Language')
}
if "dca" in codec and "dts-hd ma" in profile:
track['codec'] = "dtshd_ma"
audio_tracks.append(track)
def get_runtime(self):
try:
runtime = self.item['RunTimeTicks'] / 10000000.0
@ -214,7 +223,8 @@ class API():
return runtime
def adjustResume(self, resume_seconds):
@classmethod
def adjust_resume(cls, resume_seconds):
resume = 0
if resume_seconds:
@ -226,24 +236,23 @@ class API():
return resume
def getStudios(self):
def get_studios(self):
# Process Studios
studios = []
try:
studio = self.item['SeriesStudio']
studios.append(self.verifyStudio(studio))
studios.append(self.verify_studio(studio))
except KeyError:
studioList = self.item['Studios']
for studio in studioList:
for studio in self.item['Studios']:
name = studio['Name']
studios.append(self.verifyStudio(name))
studios.append(self.verify_studio(name))
return studios
def verifyStudio(self, studioName):
@classmethod
def verify_studio(cls, studio_name):
# Convert studio for Kodi to properly detect them
studios = {
@ -254,9 +263,9 @@ class API():
'wgn america': "WGN"
}
return studios.get(studioName.lower(), studioName)
return studios.get(studio_name.lower(), studio_name)
def getChecksum(self):
def get_checksum(self):
# Use the etags checksum and userdata
userdata = self.item['UserData']
@ -265,7 +274,7 @@ class API():
self.item['Etag'],
userdata['Played'],
userdata['IsFavorite'],
userdata.get('Likes',''),
userdata.get('Likes', ""),
userdata['PlaybackPositionTicks'],
userdata.get('UnplayedItemCount', ""),
userdata.get('LastPlayedDate', "")
@ -273,7 +282,7 @@ class API():
return checksum
def getGenres(self):
def get_genres(self):
all_genres = ""
genres = self.item.get('Genres', self.item.get('SeriesGenres'))
@ -282,17 +291,17 @@ class API():
return all_genres
def getDateCreated(self):
def get_date_created(self):
try:
dateadded = self.item['DateCreated']
dateadded = dateadded.split('.')[0].replace('T', " ")
date_added = self.item['DateCreated']
date_added = date_added.split('.')[0].replace('T', " ")
except KeyError:
dateadded = None
date_added = None
return dateadded
return date_added
def getPremiereDate(self):
def get_premiere_date(self):
try:
premiere = self.item['PremiereDate']
@ -302,7 +311,7 @@ class API():
return premiere
def getOverview(self):
def get_overview(self):
try:
overview = self.item['Overview']
@ -314,7 +323,7 @@ class API():
return overview
def getTagline(self):
def get_tagline(self):
try:
tagline = self.item['Taglines'][0]
@ -323,16 +332,16 @@ class API():
return tagline
def getProvider(self, providername):
def get_provider(self, name):
try:
provider = self.item['ProviderIds'][providername]
provider = self.item['ProviderIds'][name]
except KeyError:
provider = None
return provider
def getMpaa(self):
def get_mpaa(self):
# Convert more complex cases
mpaa = self.item.get('OfficialRating', "")
@ -342,7 +351,7 @@ class API():
return mpaa
def getCountry(self):
def get_country(self):
try:
country = self.item['ProductionLocations'][0]
@ -351,7 +360,7 @@ class API():
return country
def getFilePath(self):
def get_file_path(self):
try:
filepath = self.item['Path']

View file

@ -2,9 +2,7 @@
#################################################################################################
import json
import logging
import requests
import os
import urllib
from sqlite3 import OperationalError
@ -12,9 +10,10 @@ from sqlite3 import OperationalError
import xbmc
import xbmcgui
import xbmcvfs
import requests
import image_cache_thread
from utils import window, settings, language as lang, kodiSQL
from utils import window, settings, dialog, language as lang, kodiSQL, JSONRPC
##################################################################################################
@ -23,58 +22,54 @@ log = logging.getLogger("EMBY."+__name__)
##################################################################################################
class Artwork():
class Artwork(object):
xbmc_host = 'localhost'
xbmc_port = None
xbmc_username = None
xbmc_password = None
imageCacheThreads = []
imageCacheLimitThreads = 0
image_cache_threads = []
image_cache_limit = 0
def __init__(self):
self.enableTextureCache = settings('enableTextureCache') == "true"
self.imageCacheLimitThreads = int(settings('imageCacheLimit'))
self.imageCacheLimitThreads = int(self.imageCacheLimitThreads * 5)
log.info("Using Image Cache Thread Count: %s" % self.imageCacheLimitThreads)
self.enable_texture_cache = settings('enableTextureCache') == "true"
self.image_cache_limit = int(settings('imageCacheLimit')) * 5
log.info("image cache thread count: %s", self.image_cache_limit)
if not self.xbmc_port and self.enableTextureCache:
self.setKodiWebServerDetails()
if not self.xbmc_port and self.enable_texture_cache:
self._set_webserver_details()
self.userId = window('emby_currUser')
self.server = window('emby_server%s' % self.userId)
self.user_id = window('emby_currUser')
self.server = window('emby_server%s' % self.user_id)
def double_urlencode(self, text):
text = self.single_urlencode(text)
text = self.single_urlencode(text)
def _double_urlencode(self, text):
text = self._single_urlencode(text)
text = self._single_urlencode(text)
return text
def single_urlencode(self, text):
@classmethod
def _single_urlencode(cls, text):
# urlencode needs a utf- string
text = urllib.urlencode({'blahblahblah':text.encode("utf-8")})
text = urllib.urlencode({'blahblahblah': text.encode('utf-8')})
text = text[13:]
return text.decode("utf-8") #return the result again as unicode
return text.decode('utf-8') #return the result again as unicode
def setKodiWebServerDetails(self):
def _set_webserver_details(self):
# Get the Kodi webserver details - used to set the texture cache
get_setting_value = JSONRPC('Settings.GetSettingValue')
web_query = {
"jsonrpc": "2.0",
"id": 1,
"method": "Settings.GetSettingValue",
"params": {
"setting": "services.webserver"
}
"setting": "services.webserver"
}
result = xbmc.executeJSONRPC(json.dumps(web_query))
result = json.loads(result)
result = get_setting_value.execute(web_query)
try:
xbmc_webserver_enabled = result['result']['value']
except (KeyError, TypeError):
@ -82,48 +77,30 @@ class Artwork():
if not xbmc_webserver_enabled:
# Enable the webserver, it is disabled
set_setting_value = JSONRPC('Settings.SetSettingValue')
web_port = {
"jsonrpc": "2.0",
"id": 1,
"method": "Settings.SetSettingValue",
"params": {
"setting": "services.webserverport",
"value": 8080
}
"setting": "services.webserverport",
"value": 8080
}
result = xbmc.executeJSONRPC(json.dumps(web_port))
set_setting_value.execute(web_port)
self.xbmc_port = 8080
web_user = {
"jsonrpc": "2.0",
"id": 1,
"method": "Settings.SetSettingValue",
"params": {
"setting": "services.webserver",
"value": True
}
"setting": "services.webserver",
"value": True
}
result = xbmc.executeJSONRPC(json.dumps(web_user))
set_setting_value.execute(web_user)
self.xbmc_username = "kodi"
# Webserver already enabled
web_port = {
"jsonrpc": "2.0",
"id": 1,
"method": "Settings.GetSettingValue",
"params": {
"setting": "services.webserverport"
}
"setting": "services.webserverport"
}
result = xbmc.executeJSONRPC(json.dumps(web_port))
result = json.loads(result)
result = get_setting_value.execute(web_port)
try:
self.xbmc_port = result['result']['value']
except (TypeError, KeyError):
@ -131,16 +108,9 @@ class Artwork():
web_user = {
"jsonrpc": "2.0",
"id": 1,
"method": "Settings.GetSettingValue",
"params": {
"setting": "services.webserverusername"
}
"setting": "services.webserverusername"
}
result = xbmc.executeJSONRPC(json.dumps(web_user))
result = json.loads(result)
result = get_setting_value.execute(web_user)
try:
self.xbmc_username = result['result']['value']
except TypeError:
@ -148,29 +118,20 @@ class Artwork():
web_pass = {
"jsonrpc": "2.0",
"id": 1,
"method": "Settings.GetSettingValue",
"params": {
"setting": "services.webserverpassword"
}
"setting": "services.webserverpassword"
}
result = xbmc.executeJSONRPC(json.dumps(web_pass))
result = json.loads(result)
result = get_setting_value.execute(web_pass)
try:
self.xbmc_password = result['result']['value']
except TypeError:
pass
def fullTextureCacheSync(self):
def texture_cache_sync(self):
# This method will sync all Kodi artwork to textures13.db
# and cache them locally. This takes diskspace!
dialog = xbmcgui.Dialog()
if not dialog.yesno(
heading=lang(29999),
line1=lang(33042)):
if not dialog(type_="yesno",
heading="{emby}",
line1=lang(33042)):
return
log.info("Doing Image Cache Sync")
@ -179,135 +140,147 @@ class Artwork():
pdialog.create(lang(29999), lang(33043))
# ask to rest all existing or not
if dialog.yesno(lang(29999), lang(33044)):
log.info("Resetting all cache data first.")
# Remove all existing textures first
path = xbmc.translatePath('special://thumbnails/').decode('utf-8')
if xbmcvfs.exists(path):
allDirs, allFiles = xbmcvfs.listdir(path)
for dir in allDirs:
allDirs, allFiles = xbmcvfs.listdir(path+dir)
for file in allFiles:
if os.path.supports_unicode_filenames:
path = os.path.join(path+dir.decode('utf-8'),file.decode('utf-8'))
xbmcvfs.delete(path)
else:
xbmcvfs.delete(os.path.join(path.encode('utf-8')+dir,file))
# remove all existing data from texture DB
connection = kodiSQL('texture')
cursor = connection.cursor()
cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
rows = cursor.fetchall()
for row in rows:
tableName = row[0]
if tableName != "version":
cursor.execute("DELETE FROM " + tableName)
connection.commit()
cursor.close()
if dialog(type_="yesno", heading="{emby}", line1=lang(33044)):
log.info("Resetting all cache data first")
self._delete_cache()
# Cache all entries in video DB
connection = kodiSQL('video')
cursor = connection.cursor()
self._cache_all_video_entries(pdialog)
# Cache all entries in music DB
self._cache_all_music_entries(pdialog)
pdialog.update(100, "%s %s" % (lang(33046), len(self.image_cache_threads)))
log.info("Waiting for all threads to exit")
while len(self.image_cache_threads):
for thread in self.image_cache_threads:
if thread.is_finished:
self.image_cache_threads.remove(thread)
pdialog.update(100, "%s %s" % (lang(33046), len(self.image_cache_threads)))
log.info("Waiting for all threads to exit: %s", len(self.image_cache_threads))
xbmc.sleep(500)
pdialog.close()
def _cache_all_video_entries(self, pdialog):
conn = kodiSQL('video')
cursor = conn.cursor()
cursor.execute("SELECT url FROM art WHERE media_type != 'actor'") # dont include actors
result = cursor.fetchall()
total = len(result)
log.info("Image cache sync about to process %s images" % total)
log.info("Image cache sync about to process %s images", total)
cursor.close()
count = 0
for url in result:
if pdialog.iscanceled():
break
percentage = int((float(count) / float(total))*100)
message = "%s of %s (%s)" % (count, total, self.imageCacheThreads)
message = "%s of %s (%s)" % (count, total, len(self.image_cache_threads))
pdialog.update(percentage, "%s %s" % (lang(33045), message))
self.cacheTexture(url[0])
self.cache_texture(url[0])
count += 1
# Cache all entries in music DB
connection = kodiSQL('music')
cursor = connection.cursor()
def _cache_all_music_entries(self, pdialog):
conn = kodiSQL('music')
cursor = conn.cursor()
cursor.execute("SELECT url FROM art")
result = cursor.fetchall()
total = len(result)
log.info("Image cache sync about to process %s images" % total)
log.info("Image cache sync about to process %s images", total)
cursor.close()
count = 0
for url in result:
if pdialog.iscanceled():
break
percentage = int((float(count) / float(total))*100)
message = "%s of %s" % (count, total)
pdialog.update(percentage, "%s %s" % (lang(33045), message))
self.cacheTexture(url[0])
self.cache_texture(url[0])
count += 1
pdialog.update(100, "%s %s" % (lang(33046), len(self.imageCacheThreads)))
log.info("Waiting for all threads to exit")
while len(self.imageCacheThreads):
for thread in self.imageCacheThreads:
if thread.is_finished:
self.imageCacheThreads.remove(thread)
pdialog.update(100, "%s %s" % (lang(33046), len(self.imageCacheThreads)))
log.info("Waiting for all threads to exit: %s" % len(self.imageCacheThreads))
xbmc.sleep(500)
pdialog.close()
@classmethod
def _delete_cache(cls):
# Remove all existing textures first
path = xbmc.translatePath('special://thumbnails/').decode('utf-8')
if xbmcvfs.exists(path):
dirs, ignore_files = xbmcvfs.listdir(path)
for directory in dirs:
ignore_dirs, files = xbmcvfs.listdir(path + directory)
for file_ in files:
def addWorkerImageCacheThread(self, url):
if os.path.supports_unicode_filenames:
filename = os.path.join(path + directory.decode('utf-8'),
file_.decode('utf-8'))
else:
filename = os.path.join(path.encode('utf-8') + directory, file_)
xbmcvfs.delete(filename)
log.info("deleted: %s", filename)
# remove all existing data from texture DB
conn = kodiSQL('texture')
cursor = conn.cursor()
cursor.execute('SELECT tbl_name FROM sqlite_master WHERE type="table"')
rows = cursor.fetchall()
for row in rows:
table_name = row[0]
if table_name != "version":
cursor.execute("DELETE FROM " + table_name)
conn.commit()
cursor.close()
def _add_worker_image_thread(self, url):
while True:
# removed finished
for thread in self.imageCacheThreads:
for thread in self.image_cache_threads:
if thread.is_finished:
self.imageCacheThreads.remove(thread)
self.image_cache_threads.remove(thread)
# add a new thread or wait and retry if we hit our limit
if len(self.imageCacheThreads) < self.imageCacheLimitThreads:
newThread = image_cache_thread.ImageCacheThread()
newThread.set_url(self.double_urlencode(url))
newThread.set_host(self.xbmc_host, self.xbmc_port)
newThread.set_auth(self.xbmc_username, self.xbmc_password)
newThread.start()
self.imageCacheThreads.append(newThread)
if len(self.image_cache_threads) < self.image_cache_limit:
new_thread = image_cache_thread.ImageCacheThread()
new_thread.set_url(self._double_urlencode(url))
new_thread.set_host(self.xbmc_host, self.xbmc_port)
new_thread.set_auth(self.xbmc_username, self.xbmc_password)
new_thread.start()
self.image_cache_threads.append(new_thread)
return
else:
log.info("Waiting for empty queue spot: %s" % len(self.imageCacheThreads))
log.info("Waiting for empty queue spot: %s", len(self.image_cache_threads))
xbmc.sleep(50)
def cacheTexture(self, url):
def cache_texture(self, url):
# Cache a single image url to the texture cache
if url and self.enableTextureCache:
log.debug("Processing: %s" % url)
if url and self.enable_texture_cache:
log.debug("Processing: %s", url)
if not self.imageCacheLimitThreads:
# Add image to texture cache by simply calling it at the http endpoint
url = self.double_urlencode(url)
try: # Extreme short timeouts so we will have a exception.
response = requests.head(
url=("http://%s:%s/image/image://%s"
% (self.xbmc_host, self.xbmc_port, url)),
auth=(self.xbmc_username, self.xbmc_password),
timeout=(0.01, 0.01))
# We don't need the result
except: pass
if not self.image_cache_limit:
url = self._double_urlencode(url)
try: # Add image to texture cache by simply calling it at the http endpoint
requests.head(url=("http://%s:%s/image/image://%s"
% (self.xbmc_host, self.xbmc_port, url)),
auth=(self.xbmc_username, self.xbmc_password),
timeout=(0.01, 0.01))
except Exception: # We don't need the result
pass
else:
self.addWorkerImageCacheThread(url)
self._add_worker_image_thread(url)
def addArtwork(self, artwork, kodiId, mediaType, cursor):
def add_artwork(self, artwork, kodi_id, media_type, cursor):
# Kodi conversion table
kodiart = {
kodi_artwork = {
'Primary': ["thumb", "poster"],
'Banner': "banner",
@ -318,15 +291,14 @@ class Artwork():
'Backdrop': "fanart",
'BoxRear': "poster"
}
# Artwork is a dictionary
for art in artwork:
for artwork_type in artwork:
if art == "Backdrop":
if artwork_type == 'Backdrop':
# Backdrop entry is a list
# Process extra fanart for artwork downloader (fanart, fanart1, fanart2...)
backdrops = artwork[art]
backdropsNumber = len(backdrops)
backdrops = artwork[artwork_type]
backdrops_number = len(backdrops)
query = ' '.join((
@ -336,10 +308,10 @@ class Artwork():
"AND media_type = ?",
"AND type LIKE ?"
))
cursor.execute(query, (kodiId, mediaType, "fanart%",))
cursor.execute(query, (kodi_id, media_type, "fanart%",))
rows = cursor.fetchall()
if len(rows) > backdropsNumber:
if len(rows) > backdrops_number:
# More backdrops in database. Delete extra fanart.
query = ' '.join((
@ -348,47 +320,40 @@ class Artwork():
"AND media_type = ?",
"AND type LIKE ?"
))
cursor.execute(query, (kodiId, mediaType, "fanart_",))
cursor.execute(query, (kodi_id, media_type, "fanart_",))
# Process backdrops and extra fanart
index = ""
for backdrop in backdrops:
self.addOrUpdateArt(
imageUrl=backdrop,
kodiId=kodiId,
mediaType=mediaType,
imageType="%s%s" % ("fanart", index),
cursor=cursor)
for index, backdrop in enumerate(backdrops):
if backdropsNumber > 1:
try: # Will only fail on the first try, str to int.
index += 1
except TypeError:
index = 1
self.add_update_art(image_url=backdrop,
kodi_id=kodi_id,
media_type=media_type,
image_type=("fanart" if not index else "%s%s"
% ("fanart", index)),
cursor=cursor)
elif art == "Primary":
elif artwork_type == 'Primary':
# Primary art is processed as thumb and poster for Kodi.
for artType in kodiart[art]:
self.addOrUpdateArt(
imageUrl=artwork[art],
kodiId=kodiId,
mediaType=mediaType,
imageType=artType,
cursor=cursor)
for art_type in kodi_artwork[artwork_type]:
self.add_update_art(image_url=artwork[artwork_type],
kodi_id=kodi_id,
media_type=media_type,
image_type=art_type,
cursor=cursor)
elif kodiart.get(art):
elif artwork_type in kodi_artwork:
# Process the rest artwork type that Kodi can use
self.addOrUpdateArt(
imageUrl=artwork[art],
kodiId=kodiId,
mediaType=mediaType,
imageType=kodiart[art],
cursor=cursor)
self.add_update_art(image_url=artwork[artwork_type],
kodi_id=kodi_id,
media_type=media_type,
image_type=kodi_artwork[artwork_type],
cursor=cursor)
def addOrUpdateArt(self, imageUrl, kodiId, mediaType, imageType, cursor):
def add_update_art(self, image_url, kodi_id, media_type, image_type, cursor):
# Possible that the imageurl is an empty string
if imageUrl:
cacheimage = False
if image_url:
cache_image = False
query = ' '.join((
@ -398,13 +363,13 @@ class Artwork():
"AND media_type = ?",
"AND type = ?"
))
cursor.execute(query, (kodiId, mediaType, imageType,))
cursor.execute(query, (kodi_id, media_type, image_type,))
try: # Update the artwork
url = cursor.fetchone()[0]
except TypeError: # Add the artwork
cacheimage = True
log.debug("Adding Art Link for kodiId: %s (%s)" % (kodiId, imageUrl))
cache_image = True
log.debug("Adding Art Link for kodiId: %s (%s)", kodi_id, image_url)
query = (
'''
@ -413,20 +378,21 @@ class Artwork():
VALUES (?, ?, ?, ?)
'''
)
cursor.execute(query, (kodiId, mediaType, imageType, imageUrl))
cursor.execute(query, (kodi_id, media_type, image_type, image_url))
else: # Only cache artwork if it changed
if url != imageUrl:
cacheimage = True
if url != image_url:
cache_image = True
# Only for the main backdrop, poster
if (window('emby_initialScan') != "true" and
imageType in ("fanart", "poster")):
image_type in ("fanart", "poster")):
# Delete current entry before updating with the new one
self.deleteCachedArtwork(url)
self.delete_cached_artwork(url)
log.info("Updating Art url for %s kodiId: %s (%s) -> (%s)"
% (imageType, kodiId, url, imageUrl))
log.info("Updating Art url for %s kodiId: %s (%s) -> (%s)",
image_type, kodi_id, url, image_url)
query = ' '.join((
@ -436,13 +402,13 @@ class Artwork():
"AND media_type = ?",
"AND type = ?"
))
cursor.execute(query, (imageUrl, kodiId, mediaType, imageType))
cursor.execute(query, (image_url, kodi_id, media_type, image_type))
# Cache fanart and poster in Kodi texture cache
if cacheimage and imageType in ("fanart", "poster"):
self.cacheTexture(imageUrl)
if cache_image and image_type in ("fanart", "poster"):
self.cache_texture(image_url)
def deleteArtwork(self, kodiId, mediaType, cursor):
def delete_artwork(self, kodi_id, media_type, cursor):
query = ' '.join((
@ -451,85 +417,83 @@ class Artwork():
"WHERE media_id = ?",
"AND media_type = ?"
))
cursor.execute(query, (kodiId, mediaType,))
cursor.execute(query, (kodi_id, media_type,))
rows = cursor.fetchall()
for row in rows:
url = row[0]
imageType = row[1]
if imageType in ("poster", "fanart"):
self.deleteCachedArtwork(url)
image_type = row[1]
if image_type in ("poster", "fanart"):
self.delete_cached_artwork(url)
def deleteCachedArtwork(self, url):
@classmethod
def delete_cached_artwork(cls, url):
# Only necessary to remove and apply a new backdrop or poster
connection = kodiSQL('texture')
cursor = connection.cursor()
conn = kodiSQL('texture')
cursor = conn.cursor()
try:
cursor.execute("SELECT cachedurl FROM texture WHERE url = ?", (url,))
cachedurl = cursor.fetchone()[0]
cached_url = cursor.fetchone()[0]
except TypeError:
log.info("Could not find cached url.")
log.info("Could not find cached url")
except OperationalError:
log.info("Database is locked. Skip deletion process.")
else: # Delete thumbnail as well as the entry
thumbnails = xbmc.translatePath("special://thumbnails/%s" % cachedurl).decode('utf-8')
log.info("Deleting cached thumbnail: %s" % thumbnails)
thumbnails = xbmc.translatePath("special://thumbnails/%s", cached_url).decode('utf-8')
log.info("Deleting cached thumbnail: %s", thumbnails)
xbmcvfs.delete(thumbnails)
try:
cursor.execute("DELETE FROM texture WHERE url = ?", (url,))
connection.commit()
conn.commit()
except OperationalError:
log.debug("Issue deleting url from cache. Skipping.")
finally:
cursor.close()
def getPeopleArtwork(self, people):
def get_people_artwork(self, people):
# append imageurl if existing
for person in people:
personId = person['Id']
tag = person.get('PrimaryImageTag')
image = ""
if tag:
person_id = person['Id']
if "PrimaryImageTag" in person:
image = (
"%s/emby/Items/%s/Images/Primary?"
"MaxWidth=400&MaxHeight=400&Index=0&Tag=%s"
% (self.server, personId, tag))
% (self.server, person_id, person['PrimaryImageTag']))
person['imageurl'] = image
return people
def getUserArtwork(self, itemId, itemType):
def get_user_artwork(self, item_id, item_type):
# Load user information set by UserClient
image = ("%s/emby/Users/%s/Images/%s?Format=original"
% (self.server, itemId, itemType))
return image
return "%s/emby/Users/%s/Images/%s?Format=original" % (self.server, item_id, item_type)
def getAllArtwork(self, item, parentInfo=False):
def get_all_artwork(self, item, parent_info=False):
itemid = item['Id']
item_id = item['Id']
artworks = item['ImageTags']
backdrops = item.get('BackdropImageTags', [])
maxHeight = 10000
maxWidth = 10000
customquery = ""
max_height = 10000
max_width = 10000
custom_query = ""
if settings('compressArt') == "true":
customquery = "&Quality=90"
custom_query = "&Quality=90"
if settings('enableCoverArt') == "false":
customquery += "&EnableImageEnhancers=false"
custom_query += "&EnableImageEnhancers=false"
allartworks = {
all_artwork = {
'Primary': "",
'Art': "",
@ -540,71 +504,52 @@ class Artwork():
'Backdrop': []
}
def get_backdrops(backdrops):
for index, tag in enumerate(backdrops):
artwork = ("%s/emby/Items/%s/Images/Backdrop/%s?"
"MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s"
% (self.server, item_id, index, max_width, max_height,
tag, custom_query))
all_artwork['Backdrop'].append(artwork)
def get_artwork(type_, tag):
artwork = ("%s/emby/Items/%s/Images/%s/0?"
"MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s"
% (self.server, item_id, type_, max_width, max_height, tag, custom_query))
all_artwork[type_] = artwork
# Process backdrops
for index, tag in enumerate(backdrops):
artwork = (
"%s/emby/Items/%s/Images/Backdrop/%s?"
"MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s"
% (self.server, itemid, index, maxWidth, maxHeight, tag, customquery))
allartworks['Backdrop'].append(artwork)
get_backdrops(backdrops)
# Process the rest of the artwork
for art in artworks:
for artwork in artworks:
# Filter backcover
if art != "BoxRear":
tag = artworks[art]
artwork = (
"%s/emby/Items/%s/Images/%s/0?"
"MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s"
% (self.server, itemid, art, maxWidth, maxHeight, tag, customquery))
allartworks[art] = artwork
if artwork != "BoxRear":
get_artwork(artwork, artworks[artwork])
# Process parent items if the main item is missing artwork
if parentInfo:
if parent_info:
# Process parent backdrops
if not allartworks['Backdrop']:
if not all_artwork['Backdrop']:
parentId = item.get('ParentBackdropItemId')
if parentId:
# If there is a parentId, go through the parent backdrop list
parentbackdrops = item['ParentBackdropImageTags']
for index, tag in enumerate(parentbackdrops):
artwork = (
"%s/emby/Items/%s/Images/Backdrop/%s?"
"MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s"
% (self.server, parentId, index, maxWidth, maxHeight, tag, customquery))
allartworks['Backdrop'].append(artwork)
if 'ParentBackdropItemId' in item:
# If there is a parent_id, go through the parent backdrop list
get_backdrops(item['ParentBackdropImageTags'])
# Process the rest of the artwork
parentartwork = ['Logo', 'Art', 'Thumb']
for parentart in parentartwork:
for parent_artwork in ('Logo', 'Art', 'Thumb'):
if not allartworks[parentart]:
if not all_artwork[parent_artwork]:
parentId = item.get('Parent%sItemId' % parentart)
if parentId:
parentTag = item['Parent%sImageTag' % parentart]
artwork = (
"%s/emby/Items/%s/Images/%s/0?"
"MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s"
% (self.server, parentId, parentart,
maxWidth, maxHeight, parentTag, customquery))
allartworks[parentart] = artwork
if 'Parent%sItemId' % parent_artwork in item:
get_artwork(parent_artwork, item['Parent%sImageTag' % parent_artwork])
# Parent album works a bit differently
if not allartworks['Primary']:
if not all_artwork['Primary']:
parentId = item.get('AlbumId')
if parentId and item.get('AlbumPrimaryImageTag'):
if 'AlbumId' in item and 'AlbumPrimaryImageTag' in item:
get_artwork('Primary', item['AlbumPrimaryImageTag'])
parentTag = item['AlbumPrimaryImageTag']
artwork = (
"%s/emby/Items/%s/Images/Primary/0?"
"MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s"
% (self.server, parentId, maxWidth, maxHeight, parentTag, customquery))
allartworks['Primary'] = artwork
return allartworks
return all_artwork

View file

@ -191,7 +191,7 @@ class Embydb_Functions():
self.embycursor.execute(query, (parentid, mediatype,))
return self.embycursor.fetchall()
def getChecksum(self, mediatype):
def get_checksum(self, mediatype):
query = ' '.join((

View file

@ -319,7 +319,7 @@ def addUser():
url = "{server}/emby/Users/%s?format=json" % userid
result = doUtils.downloadUrl(url)
window('EmbyAdditionalUserImage.%s' % count,
value=art.getUserArtwork(result['Id'], 'Primary'))
value=art.get_user_artwork(result['Id'], 'Primary'))
window('EmbyAdditionalUserPosition.%s' % userid, value=str(count))
count +=1
@ -608,7 +608,7 @@ def createListItemFromEmbyItem(item,art=artwork.Artwork(),doUtils=downloadutils.
li.setProperty("embyid",itemid)
allart = art.getAllArtwork(item)
allart = art.get_all_artwork(item)
if item["Type"] == "Photo":
#listitem setup for pictures...
@ -621,16 +621,16 @@ def createListItemFromEmbyItem(item,art=artwork.Artwork(),doUtils=downloadutils.
li.setArt( {"fanart": img_path}) #add image as fanart for use with skinhelper auto thumb/backgrund creation
li.setInfo('pictures', infoLabels={ "picturepath": img_path, "date": premieredate, "size": picture.get("Size"), "exif:width": str(picture.get("Width")), "exif:height": str(picture.get("Height")), "title": title})
li.setThumbnailImage(img_path)
li.setProperty("plot",API.getOverview())
li.setProperty("plot",API.get_overview())
li.setIconImage('DefaultPicture.png')
else:
#normal video items
li.setProperty('IsPlayable', 'true')
path = "%s?id=%s&mode=play" % (sys.argv[0], item.get("Id"))
li.setProperty("path",path)
genre = API.getGenres()
genre = API.get_genres()
overlay = 0
userdata = API.getUserData()
userdata = API.get_userdata()
runtime = item.get("RunTimeTicks",0)/ 10000000.0
seektime = userdata['Resume']
if seektime:
@ -655,7 +655,7 @@ def createListItemFromEmbyItem(item,art=artwork.Artwork(),doUtils=downloadutils.
'genre': genre,
'playcount': str(playcount),
'title': title,
'plot': API.getOverview(),
'plot': API.get_overview(),
'Overlay': str(overlay),
'duration': runtime
}
@ -672,7 +672,7 @@ def createListItemFromEmbyItem(item,art=artwork.Artwork(),doUtils=downloadutils.
else:
pbutils.PlaybackUtils(item).setArtwork(li)
mediastreams = API.getMediaStreams()
mediastreams = API.get_media_streams()
videostreamFound = False
if mediastreams:
for key, value in mediastreams.iteritems():
@ -1084,7 +1084,7 @@ def getExtraFanArt(embyId,embyPath):
xbmcvfs.mkdirs(fanartDir)
item = emby.getItem(embyId)
if item:
backdrops = art.getAllArtwork(item)['Backdrop']
backdrops = art.get_all_artwork(item)['Backdrop']
tags = item['BackdropImageTags']
count = 0
for backdrop in backdrops:

View file

@ -307,31 +307,31 @@ class Movies(Items):
log.debug("View tag found: %s" % viewtag)
# fileId information
checksum = API.getChecksum()
dateadded = API.getDateCreated()
userdata = API.getUserData()
checksum = API.get_checksum()
dateadded = API.get_date_created()
userdata = API.get_userdata()
playcount = userdata['PlayCount']
dateplayed = userdata['LastPlayedDate']
# item details
people = API.getPeople()
people = API.get_people()
writer = " / ".join(people['Writer'])
director = " / ".join(people['Director'])
genres = item['Genres']
title = item['Name']
plot = API.getOverview()
plot = API.get_overview()
shortplot = item.get('ShortOverview')
tagline = API.getTagline()
tagline = API.get_tagline()
votecount = item.get('VoteCount')
rating = item.get('CommunityRating')
year = item.get('ProductionYear')
imdb = API.getProvider('Imdb')
imdb = API.get_provider('Imdb')
sorttitle = item['SortName']
runtime = API.getRuntime()
mpaa = API.getMpaa()
runtime = API.get_runtime()
mpaa = API.get_mpaa()
genre = " / ".join(genres)
country = API.getCountry()
studios = API.getStudios()
country = API.get_country()
studios = API.get_studios()
try:
studio = studios[0]
except IndexError:
@ -366,7 +366,7 @@ class Movies(Items):
##### GET THE FILE AND PATH #####
playurl = API.getFilePath()
playurl = API.get_file_path()
if "\\" in playurl:
# Local path
@ -461,14 +461,14 @@ class Movies(Items):
# Process countries
self.kodi_db.addCountries(movieid, item['ProductionLocations'], "movie")
# Process cast
people = artwork.getPeopleArtwork(item['People'])
people = artwork.get_people_artwork(item['People'])
self.kodi_db.addPeople(movieid, people, "movie")
# Process genres
self.kodi_db.addGenres(movieid, genres, "movie")
# Process artwork
artwork.addArtwork(artwork.getAllArtwork(item), movieid, "movie", kodicursor)
artwork.add_artwork(artwork.get_all_artwork(item), movieid, "movie", kodicursor)
# Process stream details
streams = API.getMediaStreams()
streams = API.get_media_streams()
self.kodi_db.addStreams(fileid, streams, runtime)
# Process studios
self.kodi_db.addStudios(movieid, studios, "movie")
@ -479,7 +479,7 @@ class Movies(Items):
tags.append("Favorite movies")
self.kodi_db.addTags(movieid, tags, "movie")
# Process playstates
resume = API.adjustResume(userdata['Resume'])
resume = API.adjust_resume(userdata['Resume'])
total = round(float(runtime), 6)
self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
@ -500,7 +500,7 @@ class Movies(Items):
setid = self.kodi_db.createBoxset(title)
# Process artwork
artwork.addArtwork(artwork.getAllArtwork(boxset), setid, "set", self.kodicursor)
artwork.add_artwork(artwork.get_all_artwork(boxset), setid, "set", self.kodicursor)
# Process movies inside boxset
current_movies = emby_db.getItemId_byParentId(setid, "movie")
@ -556,9 +556,9 @@ class Movies(Items):
# Get emby information
itemid = item['Id']
checksum = API.getChecksum()
userdata = API.getUserData()
runtime = API.getRuntime()
checksum = API.get_checksum()
userdata = API.get_userdata()
runtime = API.get_runtime()
# Get Kodi information
emby_dbitem = emby_db.getItem_byId(itemid)
@ -578,7 +578,7 @@ class Movies(Items):
# Process playstates
playcount = userdata['PlayCount']
dateplayed = userdata['LastPlayedDate']
resume = API.adjustResume(userdata['Resume'])
resume = API.adjust_resume(userdata['Resume'])
total = round(float(runtime), 6)
log.debug("%s New resume point: %s" % (itemid, resume))
@ -604,7 +604,7 @@ class Movies(Items):
# Remove the emby reference
emby_db.removeItem(itemid)
# Remove artwork
artwork.deleteArtwork(kodiid, mediatype, kodicursor)
artwork.delete_artwork(kodiid, mediatype, kodicursor)
if mediatype == "movie":
# Delete kodi movie and file
@ -693,30 +693,30 @@ class MusicVideos(Items):
log.debug("View tag found: %s" % viewtag)
# fileId information
checksum = API.getChecksum()
dateadded = API.getDateCreated()
userdata = API.getUserData()
checksum = API.get_checksum()
dateadded = API.get_date_created()
userdata = API.get_userdata()
playcount = userdata['PlayCount']
dateplayed = userdata['LastPlayedDate']
# item details
runtime = API.getRuntime()
plot = API.getOverview()
runtime = API.get_runtime()
plot = API.get_overview()
title = item['Name']
year = item.get('ProductionYear')
genres = item['Genres']
genre = " / ".join(genres)
studios = API.getStudios()
studios = API.get_studios()
studio = " / ".join(studios)
artist = " / ".join(item.get('Artists'))
album = item.get('Album')
track = item.get('Track')
people = API.getPeople()
people = API.get_people()
director = " / ".join(people['Director'])
##### GET THE FILE AND PATH #####
playurl = API.getFilePath()
playurl = API.get_file_path()
if "\\" in playurl:
# Local path
@ -833,14 +833,14 @@ class MusicVideos(Items):
for artist in artists:
artist['Type'] = "Artist"
people.extend(artists)
people = artwork.getPeopleArtwork(people)
people = artwork.get_people_artwork(people)
self.kodi_db.addPeople(mvideoid, people, "musicvideo")
# Process genres
self.kodi_db.addGenres(mvideoid, genres, "musicvideo")
# Process artwork
artwork.addArtwork(artwork.getAllArtwork(item), mvideoid, "musicvideo", kodicursor)
artwork.add_artwork(artwork.get_all_artwork(item), mvideoid, "musicvideo", kodicursor)
# Process stream details
streams = API.getMediaStreams()
streams = API.get_media_streams()
self.kodi_db.addStreams(fileid, streams, runtime)
# Process studios
self.kodi_db.addStudios(mvideoid, studios, "musicvideo")
@ -851,7 +851,7 @@ class MusicVideos(Items):
tags.append("Favorite musicvideos")
self.kodi_db.addTags(mvideoid, tags, "musicvideo")
# Process playstates
resume = API.adjustResume(userdata['Resume'])
resume = API.adjust_resume(userdata['Resume'])
total = round(float(runtime), 6)
self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
@ -863,9 +863,9 @@ class MusicVideos(Items):
# Get emby information
itemid = item['Id']
checksum = API.getChecksum()
userdata = API.getUserData()
runtime = API.getRuntime()
checksum = API.get_checksum()
userdata = API.get_userdata()
runtime = API.get_runtime()
# Get Kodi information
emby_dbitem = emby_db.getItem_byId(itemid)
@ -887,7 +887,7 @@ class MusicVideos(Items):
# Process playstates
playcount = userdata['PlayCount']
dateplayed = userdata['LastPlayedDate']
resume = API.adjustResume(userdata['Resume'])
resume = API.adjust_resume(userdata['Resume'])
total = round(float(runtime), 6)
self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
@ -922,7 +922,7 @@ class MusicVideos(Items):
url = row[0]
imagetype = row[1]
if imagetype in ("poster", "fanart"):
artwork.deleteCachedArtwork(url)
artwork.delete_cached_artwork(url)
kodicursor.execute("DELETE FROM musicvideo WHERE idMVideo = ?", (mvideoid,))
kodicursor.execute("DELETE FROM files WHERE idFile = ?", (fileid,))
@ -1033,28 +1033,28 @@ class TVShows(Items):
log.debug("View tag found: %s" % viewtag)
# fileId information
checksum = API.getChecksum()
dateadded = API.getDateCreated()
userdata = API.getUserData()
checksum = API.get_checksum()
dateadded = API.get_date_created()
userdata = API.get_userdata()
playcount = userdata['PlayCount']
dateplayed = userdata['LastPlayedDate']
# item details
genres = item['Genres']
title = item['Name']
plot = API.getOverview()
plot = API.get_overview()
rating = item.get('CommunityRating')
premieredate = API.getPremiereDate()
tvdb = API.getProvider('Tvdb')
premieredate = API.get_premiere_date()
tvdb = API.get_provider('Tvdb')
sorttitle = item['SortName']
mpaa = API.getMpaa()
mpaa = API.get_mpaa()
genre = " / ".join(genres)
studios = API.getStudios()
studios = API.get_studios()
studio = " / ".join(studios)
##### GET THE FILE AND PATH #####
playurl = API.getFilePath()
playurl = API.get_file_path()
if self.directpath:
# Direct paths is set the Kodi way
@ -1142,12 +1142,12 @@ class TVShows(Items):
kodicursor.execute(query, (path, None, None, 1, pathid))
# Process cast
people = artwork.getPeopleArtwork(item['People'])
people = artwork.get_people_artwork(item['People'])
self.kodi_db.addPeople(showid, people, "tvshow")
# Process genres
self.kodi_db.addGenres(showid, genres, "tvshow")
# Process artwork
artwork.addArtwork(artwork.getAllArtwork(item), showid, "tvshow", kodicursor)
artwork.add_artwork(artwork.get_all_artwork(item), showid, "tvshow", kodicursor)
# Process studios
self.kodi_db.addStudios(showid, studios, "tvshow")
# Process tags: view, emby tags
@ -1164,7 +1164,7 @@ class TVShows(Items):
# Finally, refresh the all season entry
seasonid = self.kodi_db.addSeason(showid, -1)
# Process artwork
artwork.addArtwork(artwork.getAllArtwork(item), seasonid, "season", kodicursor)
artwork.add_artwork(artwork.get_all_artwork(item), seasonid, "season", kodicursor)
if force_episodes:
# We needed to recreate the show entry. Re-add episodes now.
@ -1199,7 +1199,7 @@ class TVShows(Items):
emby_db.addReference(item['Id'], seasonid, "Season", "season", parentid=showid)
# Process artwork
artwork.addArtwork(artwork.getAllArtwork(item), seasonid, "season", kodicursor)
artwork.add_artwork(artwork.get_all_artwork(item), seasonid, "season", kodicursor)
def add_updateEpisode(self, item):
# Process single episode
@ -1225,7 +1225,7 @@ class TVShows(Items):
except TypeError:
update_item = False
log.info("episodeid: %s not found." % itemid)
log.debug("episodeid: %s not found." % itemid)
# episodeid
kodicursor.execute("select coalesce(max(idEpisode),0) from episode")
episodeid = kodicursor.fetchone()[0] + 1
@ -1242,21 +1242,21 @@ class TVShows(Items):
log.info("episodeid: %s missing from Kodi, repairing the entry." % episodeid)
# fileId information
checksum = API.getChecksum()
dateadded = API.getDateCreated()
userdata = API.getUserData()
checksum = API.get_checksum()
dateadded = API.get_date_created()
userdata = API.get_userdata()
playcount = userdata['PlayCount']
dateplayed = userdata['LastPlayedDate']
# item details
people = API.getPeople()
people = API.get_people()
writer = " / ".join(people['Writer'])
director = " / ".join(people['Director'])
title = item['Name']
plot = API.getOverview()
plot = API.get_overview()
rating = item.get('CommunityRating')
runtime = API.getRuntime()
premieredate = API.getPremiereDate()
runtime = API.get_runtime()
premieredate = API.get_premiere_date()
# episode details
try:
@ -1308,7 +1308,7 @@ class TVShows(Items):
##### GET THE FILE AND PATH #####
playurl = API.getFilePath()
playurl = API.get_file_path()
if "\\" in playurl:
# Local path
@ -1431,16 +1431,16 @@ class TVShows(Items):
kodicursor.execute(query, (pathid, filename, dateadded, fileid))
# Process cast
people = artwork.getPeopleArtwork(item['People'])
people = artwork.get_people_artwork(item['People'])
self.kodi_db.addPeople(episodeid, people, "episode")
# Process artwork
artworks = artwork.getAllArtwork(item)
artwork.addOrUpdateArt(artworks['Primary'], episodeid, "episode", "thumb", kodicursor)
artworks = artwork.get_all_artwork(item)
artwork.add_update_art(artworks['Primary'], episodeid, "episode", "thumb", kodicursor)
# Process stream details
streams = API.getMediaStreams()
streams = API.get_media_streams()
self.kodi_db.addStreams(fileid, streams, runtime)
# Process playstates
resume = API.adjustResume(userdata['Resume'])
resume = API.adjust_resume(userdata['Resume'])
total = round(float(runtime), 6)
self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
if not self.directpath and resume:
@ -1464,10 +1464,10 @@ class TVShows(Items):
# Get emby information
itemid = item['Id']
checksum = API.getChecksum()
userdata = API.getUserData()
runtime = API.getRuntime()
dateadded = API.getDateCreated()
checksum = API.get_checksum()
userdata = API.get_userdata()
runtime = API.get_runtime()
dateadded = API.get_date_created()
# Get Kodi information
emby_dbitem = emby_db.getItem_byId(itemid)
@ -1491,7 +1491,7 @@ class TVShows(Items):
# Process playstates
playcount = userdata['PlayCount']
dateplayed = userdata['LastPlayedDate']
resume = API.adjustResume(userdata['Resume'])
resume = API.adjust_resume(userdata['Resume'])
total = round(float(runtime), 6)
log.debug("%s New resume point: %s" % (itemid, resume))
@ -1627,7 +1627,7 @@ class TVShows(Items):
def removeShow(self, kodiid):
kodicursor = self.kodicursor
self.artwork.deleteArtwork(kodiid, "tvshow", kodicursor)
self.artwork.delete_artwork(kodiid, "tvshow", kodicursor)
kodicursor.execute("DELETE FROM tvshow WHERE idShow = ?", (kodiid,))
log.debug("Removed tvshow: %s." % kodiid)
@ -1635,7 +1635,7 @@ class TVShows(Items):
kodicursor = self.kodicursor
self.artwork.deleteArtwork(kodiid, "season", kodicursor)
self.artwork.delete_artwork(kodiid, "season", kodicursor)
kodicursor.execute("DELETE FROM seasons WHERE idSeason = ?", (kodiid,))
log.debug("Removed season: %s." % kodiid)
@ -1643,7 +1643,7 @@ class TVShows(Items):
kodicursor = self.kodicursor
self.artwork.deleteArtwork(kodiid, "episode", kodicursor)
self.artwork.delete_artwork(kodiid, "episode", kodicursor)
kodicursor.execute("DELETE FROM episode WHERE idEpisode = ?", (kodiid,))
kodicursor.execute("DELETE FROM files WHERE idFile = ?", (fileid,))
log.debug("Removed episode: %s." % kodiid)
@ -1724,16 +1724,16 @@ class Music(Items):
##### The artist details #####
lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
dateadded = API.getDateCreated()
checksum = API.getChecksum()
dateadded = API.get_date_created()
checksum = API.get_checksum()
name = item['Name']
musicBrainzId = API.getProvider('MusicBrainzArtist')
musicBrainzId = API.get_provider('MusicBrainzArtist')
genres = " / ".join(item.get('Genres'))
bio = API.getOverview()
bio = API.get_overview()
# Associate artwork
artworks = artwork.getAllArtwork(item, parentInfo=True)
artworks = artwork.get_all_artwork(item, parent_info=True)
thumb = artworks['Primary']
backdrops = artworks['Backdrop'] # List
@ -1784,7 +1784,7 @@ class Music(Items):
# Update artwork
artwork.addArtwork(artworks, artistid, "artist", kodicursor)
artwork.add_artwork(artworks, artistid, "artist", kodicursor)
def add_updateAlbum(self, item):
# Process a single artist
@ -1805,16 +1805,16 @@ class Music(Items):
##### The album details #####
lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
dateadded = API.getDateCreated()
userdata = API.getUserData()
checksum = API.getChecksum()
dateadded = API.get_date_created()
userdata = API.get_userdata()
checksum = API.get_checksum()
name = item['Name']
musicBrainzId = API.getProvider('MusicBrainzAlbum')
musicBrainzId = API.get_provider('MusicBrainzAlbum')
year = item.get('ProductionYear')
genres = item.get('Genres')
genre = " / ".join(genres)
bio = API.getOverview()
bio = API.get_overview()
rating = userdata['UserRating']
artists = item['AlbumArtists']
if not artists:
@ -1825,7 +1825,7 @@ class Music(Items):
artistname = " / ".join(artistname)
# Associate artwork
artworks = artwork.getAllArtwork(item, parentInfo=True)
artworks = artwork.get_all_artwork(item, parent_info=True)
thumb = artworks['Primary']
if thumb:
thumb = "<thumb>%s</thumb>" % thumb
@ -1952,7 +1952,7 @@ class Music(Items):
# Add genres
self.kodi_db.addMusicGenres(albumid, genres, "album")
# Update artwork
artwork.addArtwork(artworks, albumid, "album", kodicursor)
artwork.add_artwork(artworks, albumid, "album", kodicursor)
def add_updateSong(self, item):
# Process single song
@ -1974,15 +1974,15 @@ class Music(Items):
log.debug("songid: %s not found." % itemid)
##### The song details #####
checksum = API.getChecksum()
dateadded = API.getDateCreated()
userdata = API.getUserData()
checksum = API.get_checksum()
dateadded = API.get_date_created()
userdata = API.get_userdata()
playcount = userdata['PlayCount']
dateplayed = userdata['LastPlayedDate']
# item details
title = item['Name']
musicBrainzId = API.getProvider('MusicBrainzTrackId')
musicBrainzId = API.get_provider('MusicBrainzTrackId')
genres = item.get('Genres')
genre = " / ".join(genres)
artists = " / ".join(item['Artists'])
@ -1993,7 +1993,7 @@ class Music(Items):
else:
track = disc*2**16 + tracknumber
year = item.get('ProductionYear')
duration = API.getRuntime()
duration = API.get_runtime()
rating = userdata['UserRating']
#if enabled, try to get the rating from file and/or emby
@ -2001,7 +2001,7 @@ class Music(Items):
rating, comment, hasEmbeddedCover = musicutils.getAdditionalSongTags(itemid, rating, API, kodicursor, emby_db, self.enableimportsongrating, self.enableexportsongrating, self.enableupdatesongrating)
else:
hasEmbeddedCover = False
comment = API.getOverview()
comment = API.get_overview()
##### GET THE FILE AND PATH #####
@ -2009,7 +2009,7 @@ class Music(Items):
path = "%s/emby/Audio/%s/" % (self.server, itemid)
filename = "stream.mp3"
else:
playurl = API.getFilePath()
playurl = API.get_file_path()
if "\\" in playurl:
# Local path
@ -2063,7 +2063,7 @@ class Music(Items):
album_name = item.get('Album')
if album_name:
log.info("Creating virtual music album for song: %s." % itemid)
albumid = self.kodi_db.addAlbum(album_name, API.getProvider('MusicBrainzAlbum'))
albumid = self.kodi_db.addAlbum(album_name, API.get_provider('MusicBrainzAlbum'))
emby_db.addReference("%salbum%s" % (itemid, albumid), albumid, "MusicAlbum_", "album")
else:
# No album Id associated to the song.
@ -2257,14 +2257,14 @@ class Music(Items):
self.kodi_db.addMusicGenres(songid, genres, "song")
# Update artwork
allart = artwork.getAllArtwork(item, parentInfo=True)
allart = artwork.get_all_artwork(item, parent_info=True)
if hasEmbeddedCover:
allart["Primary"] = "image://music@" + artwork.single_urlencode( playurl )
artwork.addArtwork(allart, songid, "song", kodicursor)
artwork.add_artwork(allart, songid, "song", kodicursor)
if item.get('AlbumId') is None:
# Update album artwork
artwork.addArtwork(allart, albumid, "album", kodicursor)
artwork.add_artwork(allart, albumid, "album", kodicursor)
def updateUserdata(self, item):
# This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks
@ -2275,9 +2275,9 @@ class Music(Items):
# Get emby information
itemid = item['Id']
checksum = API.getChecksum()
userdata = API.getUserData()
runtime = API.getRuntime()
checksum = API.get_checksum()
userdata = API.get_userdata()
runtime = API.get_runtime()
rating = userdata['UserRating']
# Get Kodi information
@ -2401,15 +2401,15 @@ class Music(Items):
kodicursor = self.kodicursor
self.artwork.deleteArtwork(kodiId, "song", self.kodicursor)
self.artwork.delete_artwork(kodiId, "song", self.kodicursor)
self.kodicursor.execute("DELETE FROM song WHERE idSong = ?", (kodiId,))
def removeAlbum(self, kodiId):
self.artwork.deleteArtwork(kodiId, "album", self.kodicursor)
self.artwork.delete_artwork(kodiId, "album", self.kodicursor)
self.kodicursor.execute("DELETE FROM album WHERE idAlbum = ?", (kodiId,))
def removeArtist(self, kodiId):
self.artwork.deleteArtwork(kodiId, "artist", self.kodicursor)
self.artwork.delete_artwork(kodiId, "artist", self.kodicursor)
self.kodicursor.execute("DELETE FROM artist WHERE idArtist = ?", (kodiId,))

View file

@ -420,7 +420,7 @@ class Kodidb_Functions():
if "writing" in arttype:
arttype = "writer"
self.artwork.addOrUpdateArt(thumb, actorid, arttype, "thumb", self.cursor)
self.artwork.add_update_art(thumb, actorid, arttype, "thumb", self.cursor)
def addGenres(self, kodiid, genres, mediatype):

View file

@ -25,192 +25,146 @@ class KodiMonitor(xbmc.Monitor):
def __init__(self):
self.doUtils = downloadutils.DownloadUtils()
log.info("Kodi monitor started.")
self.download = downloadutils.DownloadUtils().downloadUrl
log.info("Kodi monitor started")
def onScanStarted(self, library):
log.debug("Kodi library scan %s running." % library)
log.debug("Kodi library scan %s running", library)
if library == "video":
window('emby_kodiScan', value="true")
def onScanFinished(self, library):
log.debug("Kodi library scan %s finished." % library)
log.debug("Kodi library scan %s finished", library)
if library == "video":
window('emby_kodiScan', clear=True)
def onSettingsChanged(self):
# Monitor emby settings
# Review reset setting at a later time, need to be adjusted to account for initial setup
# changes.
'''currentPath = utils.settings('useDirectPaths')
if utils.window('emby_pluginpath') != currentPath:
# Plugin path value changed. Offer to reset
log("Changed to playback mode detected", 1)
utils.window('emby_pluginpath', value=currentPath)
resp = xbmcgui.Dialog().yesno(
heading="Playback mode change detected",
line1=(
"Detected the playback mode has changed. The database "
"needs to be recreated for the change to be applied. "
"Proceed?"))
if resp:
utils.reset()'''
currentLog = settings('logLevel')
if window('emby_logLevel') != currentLog:
current_log_level = settings('logLevel')
if window('emby_logLevel') != current_log_level:
# The log level changed, set new prop
log.info("New log level: %s" % currentLog)
window('emby_logLevel', value=currentLog)
log.info("New log level: %s", current_log_level)
window('emby_logLevel', value=current_log_level)
def onNotification(self, sender, method, data):
doUtils = self.doUtils
if method not in ("Playlist.OnAdd"):
log.info("Method: %s Data: %s" % (method, data))
if method not in ('Playlist.OnAdd', 'Player.OnStop', 'Player.OnClear'):
log.info("Method: %s Data: %s", method, data)
if data:
data = json.loads(data,'utf-8')
data = json.loads(data, 'utf-8')
if method == 'Player.OnPlay':
self._on_play_(data)
if method == "Player.OnPlay":
# Set up report progress for emby playback
item = data.get('item')
try:
kodiid = item['id']
item_type = item['type']
except (KeyError, TypeError):
log.info("Item is invalid for playstate update.")
else:
if ((settings('useDirectPaths') == "1" and not item_type == "song") or
(item_type == "song" and settings('enableMusic') == "true")):
# Set up properties for player
embyconn = kodiSQL('emby')
embycursor = embyconn.cursor()
emby_db = embydb.Embydb_Functions(embycursor)
emby_dbitem = emby_db.getItem_byKodiId(kodiid, item_type)
try:
itemid = emby_dbitem[0]
except TypeError:
log.info("No kodiId returned.")
else:
url = "{server}/emby/Users/{UserId}/Items/%s?format=json" % itemid
result = doUtils.downloadUrl(url)
log.debug("Item: %s" % result)
elif method == 'VideoLibrary.OnUpdate':
self._video_update(data)
playurl = None
count = 0
while not playurl and count < 2:
try:
playurl = xbmc.Player().getPlayingFile()
except RuntimeError:
count += 1
xbmc.sleep(200)
else:
listItem = xbmcgui.ListItem()
playback = pbutils.PlaybackUtils(result)
if item_type == "song" and settings('streamMusic') == "true":
window('emby_%s.playmethod' % playurl, value="DirectStream")
else:
window('emby_%s.playmethod' % playurl, value="DirectPlay")
# Set properties for player.py
playback.setProperties(playurl, listItem)
finally:
embycursor.close()
elif method == "VideoLibrary.OnUpdate":
# Manually marking as watched/unwatched
playcount = data.get('playcount')
item = data.get('item')
try:
kodiid = item['id']
item_type = item['type']
except (KeyError, TypeError):
log.info("Item is invalid for playstate update.")
else:
# Send notification to the server.
embyconn = kodiSQL('emby')
embycursor = embyconn.cursor()
emby_db = embydb.Embydb_Functions(embycursor)
emby_dbitem = emby_db.getItem_byKodiId(kodiid, item_type)
try:
itemid = emby_dbitem[0]
except TypeError:
log.info("Could not find itemid in emby database.")
else:
# Stop from manually marking as watched unwatched, with actual playback.
if window('emby_skipWatched%s' % itemid) == "true":
# property is set in player.py
window('emby_skipWatched%s' % itemid, clear=True)
else:
# notify the server
url = "{server}/emby/Users/{UserId}/PlayedItems/%s?format=json" % itemid
if playcount != 0:
doUtils.downloadUrl(url, action_type="POST")
log.info("Mark as watched for itemid: %s" % itemid)
else:
doUtils.downloadUrl(url, action_type="DELETE")
log.info("Mark as unwatched for itemid: %s" % itemid)
finally:
embycursor.close()
elif method == "VideoLibrary.OnRemove":
# Removed function, because with plugin paths + clean library, it will wipe
# entire library if user has permissions. Instead, use the emby context menu available
# in Isengard and higher version
pass
'''try:
kodiid = data['id']
type = data['type']
except (KeyError, TypeError):
log("Item is invalid for emby deletion.", 1)
else:
# Send the delete action to the server.
embyconn = utils.kodiSQL('emby')
embycursor = embyconn.cursor()
emby_db = embydb.Embydb_Functions(embycursor)
emby_dbitem = emby_db.getItem_byKodiId(kodiid, type)
try:
itemid = emby_dbitem[0]
except TypeError:
log("Could not find itemid in emby database.", 1)
else:
if utils.settings('skipContextMenu') != "true":
resp = xbmcgui.Dialog().yesno(
heading="Confirm delete",
line1="Delete file on Emby Server?")
if not resp:
log("User skipped deletion.", 1)
embycursor.close()
return
url = "{server}/emby/Items/%s?format=json" % itemid
log("Deleting request: %s" % itemid)
doUtils.downloadUrl(url, action_type="DELETE")
finally:
embycursor.close()'''
elif method == "System.OnSleep":
elif method == 'System.OnSleep':
# Connection is going to sleep
log.info("Marking the server as offline. System.OnSleep activated.")
window('emby_online', value="sleep")
elif method == "System.OnWake":
# Allow network to wake up
xbmc.sleep(10000)
window('emby_online', value="false")
elif method == 'System.OnWake':
self._system_wake()
elif method == 'GUI.OnScreensaverDeactivated':
self._screensaver_deactivated()
def _on_play_(self, data):
# Set up report progress for emby playback
try:
item = data['item']
kodi_id = item['id']
item_type = item['type']
except (KeyError, TypeError):
log.info("Item is invalid for playstate update")
else:
if ((settings('useDirectPaths') == "1" and not item_type == "song") or
(item_type == "song" and settings('enableMusic') == "true")):
# Set up properties for player
item_id = self._get_item_id(kodi_id, item_type)
if item_id:
url = "{server}/emby/Users/{UserId}/Items/%s?format=json" % item_id
result = self.download(url)
log.debug("Item: %s", result)
playurl = None
count = 0
while not playurl and count < 2:
try:
playurl = xbmc.Player().getPlayingFile()
except RuntimeError:
count += 1
xbmc.sleep(200)
else:
listitem = xbmcgui.ListItem()
playback = pbutils.PlaybackUtils(result)
if item_type == "song" and settings('streamMusic') == "true":
window('emby_%s.playmethod' % playurl, value="DirectStream")
else:
window('emby_%s.playmethod' % playurl, value="DirectPlay")
# Set properties for player.py
playback.setProperties(playurl, listitem)
def _video_update(self, data):
# Manually marking as watched/unwatched
try:
item = data['item']
kodi_id = item['id']
item_type = item['type']
except (KeyError, TypeError):
log.info("Item is invalid for playstate update")
else:
# Send notification to the server.
item_id = self._get_item_id(kodi_id, item_type)
if item_id:
# Stop from manually marking as watched unwatched, with actual playback.
if window('emby_skipWatched%s' % item_id) == "true":
# property is set in player.py
window('emby_skipWatched%s' % item_id, clear=True)
else:
# notify the server
url = "{server}/emby/Users/{UserId}/PlayedItems/%s?format=json" % item_id
if data.get('playcount') != 0:
self.download(url, action_type="POST")
log.info("Mark as watched for itemid: %s", item_id)
else:
self.download(url, action_type="DELETE")
log.info("Mark as unwatched for itemid: %s", item_id)
@classmethod
def _system_wake(cls):
# Allow network to wake up
xbmc.sleep(10000)
window('emby_online', value="false")
window('emby_onWake', value="true")
@classmethod
def _screensaver_deactivated(cls):
if settings('dbSyncScreensaver') == "true":
xbmc.sleep(5000)
window('emby_onWake', value="true")
@classmethod
def _get_item_id(cls, kodi_id, item_type):
elif method == "GUI.OnScreensaverDeactivated":
if settings('dbSyncScreensaver') == "true":
xbmc.sleep(5000);
window('emby_onWake', value="true")
item_id = None
conn = kodiSQL('emby')
cursor = conn.cursor()
emby_db = embydb.Embydb_Functions(cursor)
db_item = emby_db.getItem_byKodiId(kodi_id, item_type)
cursor.close()
elif method == "Playlist.OnClear":
pass
try:
item_id = db_item[0]
except TypeError:
log.info("Could not retrieve item Id")
return item_id

View file

@ -1049,12 +1049,12 @@ class ManualSync(LibrarySync):
# Pull the list of movies and boxsets in Kodi
try:
all_kodimovies = dict(emby_db.getChecksum('Movie'))
all_kodimovies = dict(emby_db.get_checksum('Movie'))
except ValueError:
all_kodimovies = {}
try:
all_kodisets = dict(emby_db.getChecksum('BoxSet'))
all_kodisets = dict(emby_db.get_checksum('BoxSet'))
except ValueError:
all_kodisets = {}
@ -1088,7 +1088,7 @@ class ManualSync(LibrarySync):
all_embymoviesIds.add(itemid)
if all_kodimovies.get(itemid) != API.getChecksum():
if all_kodimovies.get(itemid) != API.get_checksum():
# Only update if movie is not in Kodi or checksum is different
updatelist.append(itemid)
@ -1179,7 +1179,7 @@ class ManualSync(LibrarySync):
# Pull the list of musicvideos in Kodi
try:
all_kodimvideos = dict(emby_db.getChecksum('MusicVideo'))
all_kodimvideos = dict(emby_db.get_checksum('MusicVideo'))
except ValueError:
all_kodimvideos = {}
@ -1211,7 +1211,7 @@ class ManualSync(LibrarySync):
all_embymvideosIds.add(itemid)
if all_kodimvideos.get(itemid) != API.getChecksum():
if all_kodimvideos.get(itemid) != API.get_checksum():
# Only update if musicvideo is not in Kodi or checksum is different
updatelist.append(itemid)
@ -1258,12 +1258,12 @@ class ManualSync(LibrarySync):
# Pull the list of tvshows and episodes in Kodi
try:
all_koditvshows = dict(emby_db.getChecksum('Series'))
all_koditvshows = dict(emby_db.get_checksum('Series'))
except ValueError:
all_koditvshows = {}
try:
all_kodiepisodes = dict(emby_db.getChecksum('Episode'))
all_kodiepisodes = dict(emby_db.get_checksum('Episode'))
except ValueError:
all_kodiepisodes = {}
@ -1297,7 +1297,7 @@ class ManualSync(LibrarySync):
all_embytvshowsIds.add(itemid)
if all_koditvshows.get(itemid) != API.getChecksum():
if all_koditvshows.get(itemid) != API.get_checksum():
# Only update if movie is not in Kodi or checksum is different
updatelist.append(itemid)
@ -1341,7 +1341,7 @@ class ManualSync(LibrarySync):
itemid = embyepisode['Id']
all_embyepisodesIds.add(itemid)
if all_kodiepisodes.get(itemid) != API.getChecksum():
if all_kodiepisodes.get(itemid) != API.get_checksum():
# Only update if movie is not in Kodi or checksum is different
updatelist.append(itemid)
@ -1388,17 +1388,17 @@ class ManualSync(LibrarySync):
# Pull the list of artists, albums, songs
try:
all_kodiartists = dict(emby_db.getChecksum('MusicArtist'))
all_kodiartists = dict(emby_db.get_checksum('MusicArtist'))
except ValueError:
all_kodiartists = {}
try:
all_kodialbums = dict(emby_db.getChecksum('MusicAlbum'))
all_kodialbums = dict(emby_db.get_checksum('MusicAlbum'))
except ValueError:
all_kodialbums = {}
try:
all_kodisongs = dict(emby_db.getChecksum('Audio'))
all_kodisongs = dict(emby_db.get_checksum('Audio'))
except ValueError:
all_kodisongs = {}
@ -1429,17 +1429,17 @@ class ManualSync(LibrarySync):
itemid = embyitem['Id']
if data_type == "artists":
all_embyartistsIds.add(itemid)
if all_kodiartists.get(itemid) != API.getChecksum():
if all_kodiartists.get(itemid) != API.get_checksum():
# Only update if artist is not in Kodi or checksum is different
updatelist.append(itemid)
elif data_type == "albums":
all_embyalbumsIds.add(itemid)
if all_kodialbums.get(itemid) != API.getChecksum():
if all_kodialbums.get(itemid) != API.get_checksum():
# Only update if album is not in Kodi or checksum is different
updatelist.append(itemid)
else:
all_embysongsIds.add(itemid)
if all_kodisongs.get(itemid) != API.getChecksum():
if all_kodisongs.get(itemid) != API.get_checksum():
# Only update if songs is not in Kodi or checksum is different
updatelist.append(itemid)
log.info("%s to update: %s" % (data_type, updatelist))

View file

@ -74,7 +74,7 @@ def getAdditionalSongTags(embyid, emby_rating, API, kodicursor, emby_db, enablei
emby = embyserver.Read_EmbyServer()
previous_values = None
filename = API.getFilePath()
filename = API.get_file_path()
rating = 0
emby_rating = int(round(emby_rating, 0))

View file

@ -82,8 +82,8 @@ class PlaybackUtils():
############### RESUME POINT ################
userdata = self.API.getUserData()
seektime = self.API.adjustResume(userdata['Resume'])
userdata = self.API.get_userdata()
seektime = self.API.adjust_resume(userdata['Resume'])
# We need to ensure we add the intro and additional parts only once.
# Otherwise we get a loop.
@ -309,7 +309,7 @@ class PlaybackUtils():
def setArtwork(self, listItem):
# Set up item and item info
allartwork = self.artwork.getAllArtwork(self.item, parentInfo=True)
allartwork = self.artwork.get_all_artwork(self.item, parent_info=True)
# Set artwork for listitem
arttypes = {
@ -346,20 +346,20 @@ class PlaybackUtils():
def setListItem(self, listItem):
people = self.API.getPeople()
studios = self.API.getStudios()
people = self.API.get_people()
studios = self.API.get_studios()
metadata = {
'title': self.item.get('Name', "Missing name"),
'year': self.item.get('ProductionYear'),
'plot': self.API.getOverview(),
'plot': self.API.get_overview(),
'director': people.get('Director'),
'writer': people.get('Writer'),
'mpaa': self.API.getMpaa(),
'mpaa': self.API.get_mpaa(),
'genre': " / ".join(self.item['Genres']),
'studio': " / ".join(studios),
'aired': self.API.getPremiereDate(),
'aired': self.API.get_premiere_date(),
'rating': self.item.get('CommunityRating'),
'votes': self.item.get('VoteCount')
}

View file

@ -147,7 +147,7 @@ class UserClient(threading.Thread):
settings('username', value=self._user['Name'])
if "PrimaryImageTag" in self._user:
window('EmbyUserImage',
value=artwork.Artwork().getUserArtwork(self._user['Id'], 'Primary'))
value=artwork.Artwork().get_user_artwork(self._user['Id'], 'Primary'))
self._server = self.download("{server}/emby/System/Configuration?format=json")
settings('markPlayed', value=str(self._server['MaxResumePct']))