mirror of
https://github.com/jellyfin/jellyfin-kodi.git
synced 2025-06-02 14:26:14 +00:00
Pylint (#60)
This commit is contained in:
parent
cd06049e86
commit
b34007f727
13 changed files with 640 additions and 732 deletions
|
@ -109,7 +109,7 @@ class ContextMenu(object):
|
||||||
|
|
||||||
def _select_menu(self):
|
def _select_menu(self):
|
||||||
# Display select dialog
|
# Display select dialog
|
||||||
userdata = self.api.getUserData()
|
userdata = self.api.get_userdata()
|
||||||
options = []
|
options = []
|
||||||
|
|
||||||
if userdata['Favorite']:
|
if userdata['Favorite']:
|
||||||
|
@ -178,7 +178,7 @@ class ContextMenu(object):
|
||||||
new_value = 5
|
new_value = 5
|
||||||
|
|
||||||
if settings('enableUpdateSongRating') == "true":
|
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 = ?"
|
query = "UPDATE song SET rating = ? WHERE idSong = ?"
|
||||||
cursor.execute(query, (new_value, self.kodi_id,))
|
cursor.execute(query, (new_value, self.kodi_id,))
|
||||||
|
|
|
@ -70,7 +70,7 @@ class Main(object):
|
||||||
|
|
||||||
elif mode == 'texturecache':
|
elif mode == 'texturecache':
|
||||||
import artwork
|
import artwork
|
||||||
artwork.Artwork().fullTextureCacheSync()
|
artwork.Artwork().texture_cache_sync()
|
||||||
else:
|
else:
|
||||||
entrypoint.doMainListing()
|
entrypoint.doMainListing()
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ class Main(object):
|
||||||
dialog(type_="ok",
|
dialog(type_="ok",
|
||||||
heading="{emby}",
|
heading="{emby}",
|
||||||
line1=lang(33034))
|
line1=lang(33034))
|
||||||
log.warn("Not connected to the emby server.")
|
log.warn("Not connected to the emby server")
|
||||||
|
|
||||||
elif window('emby_dbScan') != "true":
|
elif window('emby_dbScan') != "true":
|
||||||
import librarysync
|
import librarysync
|
||||||
|
@ -149,7 +149,7 @@ class Main(object):
|
||||||
else:
|
else:
|
||||||
library_sync.fullSync(repair=True)
|
library_sync.fullSync(repair=True)
|
||||||
else:
|
else:
|
||||||
log.warn("Database scan is already running.")
|
log.warn("Database scan is already running")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -14,45 +14,42 @@ log = logging.getLogger("EMBY."+__name__)
|
||||||
##################################################################################################
|
##################################################################################################
|
||||||
|
|
||||||
|
|
||||||
class API():
|
class API(object):
|
||||||
|
|
||||||
def __init__(self, item):
|
def __init__(self, item):
|
||||||
|
|
||||||
# item is the api response
|
# item is the api response
|
||||||
self.item = item
|
self.item = item
|
||||||
|
|
||||||
def getUserData(self):
|
def get_userdata(self):
|
||||||
# Default
|
# Default
|
||||||
favorite = False
|
favorite = False
|
||||||
likes = None
|
likes = None
|
||||||
playcount = None
|
playcount = None
|
||||||
played = False
|
played = False
|
||||||
lastPlayedDate = None
|
last_played = None
|
||||||
resume = 0
|
resume = 0
|
||||||
userrating = 0
|
user_rating = 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
userdata = self.item['UserData']
|
userdata = self.item['UserData']
|
||||||
|
|
||||||
except KeyError: # No userdata found.
|
except KeyError: # No userdata found.
|
||||||
pass
|
pass
|
||||||
|
|
||||||
else:
|
else:
|
||||||
favorite = userdata['IsFavorite']
|
favorite = userdata['IsFavorite']
|
||||||
likes = userdata.get('Likes')
|
likes = userdata.get('Likes')
|
||||||
# Userrating is based on likes and favourite
|
# Userrating is based on likes and favourite
|
||||||
if favorite:
|
if favorite:
|
||||||
userrating = 5
|
user_rating = 5
|
||||||
elif likes:
|
elif likes:
|
||||||
userrating = 3
|
user_rating = 3
|
||||||
elif likes == False:
|
elif likes is False:
|
||||||
userrating = 0
|
user_rating = 0
|
||||||
else:
|
else:
|
||||||
userrating = 1
|
user_rating = 1
|
||||||
|
|
||||||
lastPlayedDate = userdata.get('LastPlayedDate')
|
last_played = userdata.get('LastPlayedDate')
|
||||||
if lastPlayedDate:
|
if last_played:
|
||||||
lastPlayedDate = lastPlayedDate.split('.')[0].replace('T', " ")
|
last_played = last_played.split('.')[0].replace('T', " ")
|
||||||
|
|
||||||
if userdata['Played']:
|
if userdata['Played']:
|
||||||
# Playcount is tied to the watch status
|
# Playcount is tied to the watch status
|
||||||
|
@ -61,12 +58,12 @@ class API():
|
||||||
if playcount == 0:
|
if playcount == 0:
|
||||||
playcount = 1
|
playcount = 1
|
||||||
|
|
||||||
if lastPlayedDate is None:
|
if last_played is None:
|
||||||
lastPlayedDate = self.getDateCreated()
|
last_played = self.get_date_created()
|
||||||
|
|
||||||
playbackPosition = userdata.get('PlaybackPositionTicks')
|
playback_position = userdata.get('PlaybackPositionTicks')
|
||||||
if playbackPosition:
|
if playback_position:
|
||||||
resume = playbackPosition / 10000000.0
|
resume = playback_position / 10000000.0
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
||||||
|
@ -74,12 +71,12 @@ class API():
|
||||||
'Likes': likes,
|
'Likes': likes,
|
||||||
'PlayCount': playcount,
|
'PlayCount': playcount,
|
||||||
'Played': played,
|
'Played': played,
|
||||||
'LastPlayedDate': lastPlayedDate,
|
'LastPlayedDate': last_played,
|
||||||
'Resume': resume,
|
'Resume': resume,
|
||||||
'UserRating': userrating
|
'UserRating': user_rating
|
||||||
}
|
}
|
||||||
|
|
||||||
def getPeople(self):
|
def get_people(self):
|
||||||
# Process People
|
# Process People
|
||||||
director = []
|
director = []
|
||||||
writer = []
|
writer = []
|
||||||
|
@ -87,21 +84,19 @@ class API():
|
||||||
|
|
||||||
try:
|
try:
|
||||||
people = self.item['People']
|
people = self.item['People']
|
||||||
|
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
else:
|
else:
|
||||||
for person in people:
|
for person in people:
|
||||||
|
|
||||||
type = person['Type']
|
type_ = person['Type']
|
||||||
name = person['Name']
|
name = person['Name']
|
||||||
|
|
||||||
if "Director" in type:
|
if type_ == 'Director':
|
||||||
director.append(name)
|
director.append(name)
|
||||||
elif "Actor" in type:
|
elif type_ == 'Actor':
|
||||||
cast.append(name)
|
cast.append(name)
|
||||||
elif type in ("Writing", "Writer"):
|
elif type_ in ('Writing', 'Writer'):
|
||||||
writer.append(name)
|
writer.append(name)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -111,38 +106,58 @@ class API():
|
||||||
'Cast': cast
|
'Cast': cast
|
||||||
}
|
}
|
||||||
|
|
||||||
def getMediaStreams(self):
|
def get_media_streams(self):
|
||||||
videotracks = []
|
|
||||||
audiotracks = []
|
video_tracks = []
|
||||||
subtitlelanguages = []
|
audio_tracks = []
|
||||||
|
subtitle_languages = []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
media_streams = self.item['MediaSources'][0]['MediaStreams']
|
media_streams = self.item['MediaSources'][0]['MediaStreams']
|
||||||
|
|
||||||
except KeyError:
|
except KeyError:
|
||||||
if not self.item.get("MediaStreams"): return None
|
if not self.item.get("MediaStreams"):
|
||||||
|
return None
|
||||||
media_streams = self.item['MediaStreams']
|
media_streams = self.item['MediaStreams']
|
||||||
|
|
||||||
for media_stream in media_streams:
|
for media_stream in media_streams:
|
||||||
# Sort through Video, Audio, Subtitle
|
# Sort through Video, Audio, Subtitle
|
||||||
stream_type = media_stream['Type']
|
stream_type = media_stream['Type']
|
||||||
codec = media_stream.get('Codec', "").lower()
|
|
||||||
profile = media_stream.get('Profile', "").lower()
|
|
||||||
|
|
||||||
if stream_type == "Video":
|
if stream_type == "Video":
|
||||||
|
self._video_stream(video_tracks, media_stream)
|
||||||
|
|
||||||
|
elif stream_type == "Audio":
|
||||||
|
self._audio_stream(audio_tracks, media_stream)
|
||||||
|
|
||||||
|
elif stream_type == "Subtitle":
|
||||||
|
subtitle_languages.append(media_stream.get('Language', "Unknown"))
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
'video': video_tracks,
|
||||||
|
'audio': audio_tracks,
|
||||||
|
'subtitle': subtitle_languages
|
||||||
|
}
|
||||||
|
|
||||||
|
def _video_stream(self, video_tracks, stream):
|
||||||
|
|
||||||
|
codec = stream.get('Codec', "").lower()
|
||||||
|
profile = stream.get('Profile', "").lower()
|
||||||
|
|
||||||
# Height, Width, Codec, AspectRatio, AspectFloat, 3D
|
# Height, Width, Codec, AspectRatio, AspectFloat, 3D
|
||||||
track = {
|
track = {
|
||||||
|
|
||||||
'codec': codec,
|
'codec': codec,
|
||||||
'height': media_stream.get('Height'),
|
'height': stream.get('Height'),
|
||||||
'width': media_stream.get('Width'),
|
'width': stream.get('Width'),
|
||||||
'video3DFormat': self.item.get('Video3DFormat'),
|
'video3DFormat': self.item.get('Video3DFormat'),
|
||||||
'aspect': 1.85
|
'aspect': 1.85
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
container = self.item['MediaSources'][0]['Container'].lower()
|
container = self.item['MediaSources'][0]['Container'].lower()
|
||||||
except:
|
except Exception:
|
||||||
container = ""
|
container = ""
|
||||||
|
|
||||||
# Sort codec vs container/profile
|
# Sort codec vs container/profile
|
||||||
|
@ -156,17 +171,18 @@ class API():
|
||||||
track['codec'] = "avc1"
|
track['codec'] = "avc1"
|
||||||
|
|
||||||
# Aspect ratio
|
# Aspect ratio
|
||||||
if self.item.get('AspectRatio'):
|
if 'AspectRatio' in self.item:
|
||||||
# Metadata AR
|
# Metadata AR
|
||||||
aspect = self.item['AspectRatio']
|
aspect = self.item['AspectRatio']
|
||||||
else: # File AR
|
else: # File AR
|
||||||
aspect = media_stream.get('AspectRatio', "0")
|
aspect = stream.get('AspectRatio', "0")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
aspectwidth, aspectheight = aspect.split(':')
|
aspect_width, aspect_height = aspect.split(':')
|
||||||
track['aspect'] = round(float(aspectwidth) / float(aspectheight), 6)
|
track['aspect'] = round(float(aspect_width) / float(aspect_height), 6)
|
||||||
|
|
||||||
except (ValueError, ZeroDivisionError):
|
except (ValueError, ZeroDivisionError):
|
||||||
|
|
||||||
width = track.get('width')
|
width = track.get('width')
|
||||||
height = track.get('height')
|
height = track.get('height')
|
||||||
|
|
||||||
|
@ -175,37 +191,30 @@ class API():
|
||||||
else:
|
else:
|
||||||
track['aspect'] = 1.85
|
track['aspect'] = 1.85
|
||||||
|
|
||||||
if self.item.get("RunTimeTicks"):
|
if 'RunTimeTicks' in self.item:
|
||||||
track['duration'] = self.item.get("RunTimeTicks") / 10000000.0
|
track['duration'] = self.get_runtime()
|
||||||
|
|
||||||
videotracks.append(track)
|
video_tracks.append(track)
|
||||||
|
|
||||||
elif stream_type == "Audio":
|
def _audio_stream(self, audio_tracks, stream):
|
||||||
|
|
||||||
|
codec = stream.get('Codec', "").lower()
|
||||||
|
profile = stream.get('Profile', "").lower()
|
||||||
# Codec, Channels, language
|
# Codec, Channels, language
|
||||||
track = {
|
track = {
|
||||||
|
|
||||||
'codec': codec,
|
'codec': codec,
|
||||||
'channels': media_stream.get('Channels'),
|
'channels': stream.get('Channels'),
|
||||||
'language': media_stream.get('Language')
|
'language': stream.get('Language')
|
||||||
}
|
}
|
||||||
|
|
||||||
if "dca" in codec and "dts-hd ma" in profile:
|
if "dca" in codec and "dts-hd ma" in profile:
|
||||||
track['codec'] = "dtshd_ma"
|
track['codec'] = "dtshd_ma"
|
||||||
|
|
||||||
audiotracks.append(track)
|
audio_tracks.append(track)
|
||||||
|
|
||||||
elif stream_type == "Subtitle":
|
def get_runtime(self):
|
||||||
# Language
|
|
||||||
subtitlelanguages.append(media_stream.get('Language', "Unknown"))
|
|
||||||
|
|
||||||
return {
|
|
||||||
|
|
||||||
'video': videotracks,
|
|
||||||
'audio': audiotracks,
|
|
||||||
'subtitle': subtitlelanguages
|
|
||||||
}
|
|
||||||
|
|
||||||
def getRuntime(self):
|
|
||||||
try:
|
try:
|
||||||
runtime = self.item['RunTimeTicks'] / 10000000.0
|
runtime = self.item['RunTimeTicks'] / 10000000.0
|
||||||
|
|
||||||
|
@ -214,7 +223,8 @@ class API():
|
||||||
|
|
||||||
return runtime
|
return runtime
|
||||||
|
|
||||||
def adjustResume(self, resume_seconds):
|
@classmethod
|
||||||
|
def adjust_resume(cls, resume_seconds):
|
||||||
|
|
||||||
resume = 0
|
resume = 0
|
||||||
if resume_seconds:
|
if resume_seconds:
|
||||||
|
@ -226,24 +236,23 @@ class API():
|
||||||
|
|
||||||
return resume
|
return resume
|
||||||
|
|
||||||
def getStudios(self):
|
def get_studios(self):
|
||||||
# Process Studios
|
# Process Studios
|
||||||
studios = []
|
studios = []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
studio = self.item['SeriesStudio']
|
studio = self.item['SeriesStudio']
|
||||||
studios.append(self.verifyStudio(studio))
|
studios.append(self.verify_studio(studio))
|
||||||
|
|
||||||
except KeyError:
|
except KeyError:
|
||||||
studioList = self.item['Studios']
|
for studio in self.item['Studios']:
|
||||||
for studio in studioList:
|
|
||||||
|
|
||||||
name = studio['Name']
|
name = studio['Name']
|
||||||
studios.append(self.verifyStudio(name))
|
studios.append(self.verify_studio(name))
|
||||||
|
|
||||||
return studios
|
return studios
|
||||||
|
|
||||||
def verifyStudio(self, studioName):
|
@classmethod
|
||||||
|
def verify_studio(cls, studio_name):
|
||||||
# Convert studio for Kodi to properly detect them
|
# Convert studio for Kodi to properly detect them
|
||||||
studios = {
|
studios = {
|
||||||
|
|
||||||
|
@ -254,9 +263,9 @@ class API():
|
||||||
'wgn america': "WGN"
|
'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
|
# Use the etags checksum and userdata
|
||||||
userdata = self.item['UserData']
|
userdata = self.item['UserData']
|
||||||
|
|
||||||
|
@ -265,7 +274,7 @@ class API():
|
||||||
self.item['Etag'],
|
self.item['Etag'],
|
||||||
userdata['Played'],
|
userdata['Played'],
|
||||||
userdata['IsFavorite'],
|
userdata['IsFavorite'],
|
||||||
userdata.get('Likes',''),
|
userdata.get('Likes', ""),
|
||||||
userdata['PlaybackPositionTicks'],
|
userdata['PlaybackPositionTicks'],
|
||||||
userdata.get('UnplayedItemCount', ""),
|
userdata.get('UnplayedItemCount', ""),
|
||||||
userdata.get('LastPlayedDate', "")
|
userdata.get('LastPlayedDate', "")
|
||||||
|
@ -273,7 +282,7 @@ class API():
|
||||||
|
|
||||||
return checksum
|
return checksum
|
||||||
|
|
||||||
def getGenres(self):
|
def get_genres(self):
|
||||||
all_genres = ""
|
all_genres = ""
|
||||||
genres = self.item.get('Genres', self.item.get('SeriesGenres'))
|
genres = self.item.get('Genres', self.item.get('SeriesGenres'))
|
||||||
|
|
||||||
|
@ -282,17 +291,17 @@ class API():
|
||||||
|
|
||||||
return all_genres
|
return all_genres
|
||||||
|
|
||||||
def getDateCreated(self):
|
def get_date_created(self):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
dateadded = self.item['DateCreated']
|
date_added = self.item['DateCreated']
|
||||||
dateadded = dateadded.split('.')[0].replace('T', " ")
|
date_added = date_added.split('.')[0].replace('T', " ")
|
||||||
except KeyError:
|
except KeyError:
|
||||||
dateadded = None
|
date_added = None
|
||||||
|
|
||||||
return dateadded
|
return date_added
|
||||||
|
|
||||||
def getPremiereDate(self):
|
def get_premiere_date(self):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
premiere = self.item['PremiereDate']
|
premiere = self.item['PremiereDate']
|
||||||
|
@ -302,7 +311,7 @@ class API():
|
||||||
|
|
||||||
return premiere
|
return premiere
|
||||||
|
|
||||||
def getOverview(self):
|
def get_overview(self):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
overview = self.item['Overview']
|
overview = self.item['Overview']
|
||||||
|
@ -314,7 +323,7 @@ class API():
|
||||||
|
|
||||||
return overview
|
return overview
|
||||||
|
|
||||||
def getTagline(self):
|
def get_tagline(self):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tagline = self.item['Taglines'][0]
|
tagline = self.item['Taglines'][0]
|
||||||
|
@ -323,16 +332,16 @@ class API():
|
||||||
|
|
||||||
return tagline
|
return tagline
|
||||||
|
|
||||||
def getProvider(self, providername):
|
def get_provider(self, name):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
provider = self.item['ProviderIds'][providername]
|
provider = self.item['ProviderIds'][name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
provider = None
|
provider = None
|
||||||
|
|
||||||
return provider
|
return provider
|
||||||
|
|
||||||
def getMpaa(self):
|
def get_mpaa(self):
|
||||||
# Convert more complex cases
|
# Convert more complex cases
|
||||||
mpaa = self.item.get('OfficialRating', "")
|
mpaa = self.item.get('OfficialRating', "")
|
||||||
|
|
||||||
|
@ -342,7 +351,7 @@ class API():
|
||||||
|
|
||||||
return mpaa
|
return mpaa
|
||||||
|
|
||||||
def getCountry(self):
|
def get_country(self):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
country = self.item['ProductionLocations'][0]
|
country = self.item['ProductionLocations'][0]
|
||||||
|
@ -351,7 +360,7 @@ class API():
|
||||||
|
|
||||||
return country
|
return country
|
||||||
|
|
||||||
def getFilePath(self):
|
def get_file_path(self):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
filepath = self.item['Path']
|
filepath = self.item['Path']
|
||||||
|
|
|
@ -2,9 +2,7 @@
|
||||||
|
|
||||||
#################################################################################################
|
#################################################################################################
|
||||||
|
|
||||||
import json
|
|
||||||
import logging
|
import logging
|
||||||
import requests
|
|
||||||
import os
|
import os
|
||||||
import urllib
|
import urllib
|
||||||
from sqlite3 import OperationalError
|
from sqlite3 import OperationalError
|
||||||
|
@ -12,9 +10,10 @@ from sqlite3 import OperationalError
|
||||||
import xbmc
|
import xbmc
|
||||||
import xbmcgui
|
import xbmcgui
|
||||||
import xbmcvfs
|
import xbmcvfs
|
||||||
|
import requests
|
||||||
|
|
||||||
import image_cache_thread
|
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_host = 'localhost'
|
||||||
xbmc_port = None
|
xbmc_port = None
|
||||||
xbmc_username = None
|
xbmc_username = None
|
||||||
xbmc_password = None
|
xbmc_password = None
|
||||||
|
|
||||||
imageCacheThreads = []
|
image_cache_threads = []
|
||||||
imageCacheLimitThreads = 0
|
image_cache_limit = 0
|
||||||
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
self.enableTextureCache = settings('enableTextureCache') == "true"
|
self.enable_texture_cache = settings('enableTextureCache') == "true"
|
||||||
self.imageCacheLimitThreads = int(settings('imageCacheLimit'))
|
self.image_cache_limit = int(settings('imageCacheLimit')) * 5
|
||||||
self.imageCacheLimitThreads = int(self.imageCacheLimitThreads * 5)
|
log.info("image cache thread count: %s", self.image_cache_limit)
|
||||||
log.info("Using Image Cache Thread Count: %s" % self.imageCacheLimitThreads)
|
|
||||||
|
|
||||||
if not self.xbmc_port and self.enableTextureCache:
|
if not self.xbmc_port and self.enable_texture_cache:
|
||||||
self.setKodiWebServerDetails()
|
self._set_webserver_details()
|
||||||
|
|
||||||
self.userId = window('emby_currUser')
|
self.user_id = window('emby_currUser')
|
||||||
self.server = window('emby_server%s' % self.userId)
|
self.server = window('emby_server%s' % self.user_id)
|
||||||
|
|
||||||
|
|
||||||
def double_urlencode(self, text):
|
def _double_urlencode(self, text):
|
||||||
text = self.single_urlencode(text)
|
|
||||||
text = self.single_urlencode(text)
|
text = self._single_urlencode(text)
|
||||||
|
text = self._single_urlencode(text)
|
||||||
|
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def single_urlencode(self, text):
|
@classmethod
|
||||||
|
def _single_urlencode(cls, text):
|
||||||
# urlencode needs a utf- string
|
# urlencode needs a utf- string
|
||||||
text = urllib.urlencode({'blahblahblah':text.encode("utf-8")})
|
text = urllib.urlencode({'blahblahblah': text.encode('utf-8')})
|
||||||
text = text[13:]
|
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 the Kodi webserver details - used to set the texture cache
|
||||||
web_query = {
|
get_setting_value = JSONRPC('Settings.GetSettingValue')
|
||||||
|
|
||||||
"jsonrpc": "2.0",
|
web_query = {
|
||||||
"id": 1,
|
|
||||||
"method": "Settings.GetSettingValue",
|
|
||||||
"params": {
|
|
||||||
|
|
||||||
"setting": "services.webserver"
|
"setting": "services.webserver"
|
||||||
}
|
}
|
||||||
}
|
result = get_setting_value.execute(web_query)
|
||||||
result = xbmc.executeJSONRPC(json.dumps(web_query))
|
|
||||||
result = json.loads(result)
|
|
||||||
try:
|
try:
|
||||||
xbmc_webserver_enabled = result['result']['value']
|
xbmc_webserver_enabled = result['result']['value']
|
||||||
except (KeyError, TypeError):
|
except (KeyError, TypeError):
|
||||||
|
@ -82,48 +77,30 @@ class Artwork():
|
||||||
|
|
||||||
if not xbmc_webserver_enabled:
|
if not xbmc_webserver_enabled:
|
||||||
# Enable the webserver, it is disabled
|
# Enable the webserver, it is disabled
|
||||||
web_port = {
|
set_setting_value = JSONRPC('Settings.SetSettingValue')
|
||||||
|
|
||||||
"jsonrpc": "2.0",
|
web_port = {
|
||||||
"id": 1,
|
|
||||||
"method": "Settings.SetSettingValue",
|
|
||||||
"params": {
|
|
||||||
|
|
||||||
"setting": "services.webserverport",
|
"setting": "services.webserverport",
|
||||||
"value": 8080
|
"value": 8080
|
||||||
}
|
}
|
||||||
}
|
set_setting_value.execute(web_port)
|
||||||
result = xbmc.executeJSONRPC(json.dumps(web_port))
|
|
||||||
self.xbmc_port = 8080
|
self.xbmc_port = 8080
|
||||||
|
|
||||||
web_user = {
|
web_user = {
|
||||||
|
|
||||||
"jsonrpc": "2.0",
|
|
||||||
"id": 1,
|
|
||||||
"method": "Settings.SetSettingValue",
|
|
||||||
"params": {
|
|
||||||
|
|
||||||
"setting": "services.webserver",
|
"setting": "services.webserver",
|
||||||
"value": True
|
"value": True
|
||||||
}
|
}
|
||||||
}
|
set_setting_value.execute(web_user)
|
||||||
result = xbmc.executeJSONRPC(json.dumps(web_user))
|
|
||||||
self.xbmc_username = "kodi"
|
self.xbmc_username = "kodi"
|
||||||
|
|
||||||
|
|
||||||
# Webserver already enabled
|
# Webserver already enabled
|
||||||
web_port = {
|
web_port = {
|
||||||
|
|
||||||
"jsonrpc": "2.0",
|
|
||||||
"id": 1,
|
|
||||||
"method": "Settings.GetSettingValue",
|
|
||||||
"params": {
|
|
||||||
|
|
||||||
"setting": "services.webserverport"
|
"setting": "services.webserverport"
|
||||||
}
|
}
|
||||||
}
|
result = get_setting_value.execute(web_port)
|
||||||
result = xbmc.executeJSONRPC(json.dumps(web_port))
|
|
||||||
result = json.loads(result)
|
|
||||||
try:
|
try:
|
||||||
self.xbmc_port = result['result']['value']
|
self.xbmc_port = result['result']['value']
|
||||||
except (TypeError, KeyError):
|
except (TypeError, KeyError):
|
||||||
|
@ -131,16 +108,9 @@ class Artwork():
|
||||||
|
|
||||||
web_user = {
|
web_user = {
|
||||||
|
|
||||||
"jsonrpc": "2.0",
|
|
||||||
"id": 1,
|
|
||||||
"method": "Settings.GetSettingValue",
|
|
||||||
"params": {
|
|
||||||
|
|
||||||
"setting": "services.webserverusername"
|
"setting": "services.webserverusername"
|
||||||
}
|
}
|
||||||
}
|
result = get_setting_value.execute(web_user)
|
||||||
result = xbmc.executeJSONRPC(json.dumps(web_user))
|
|
||||||
result = json.loads(result)
|
|
||||||
try:
|
try:
|
||||||
self.xbmc_username = result['result']['value']
|
self.xbmc_username = result['result']['value']
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
@ -148,28 +118,19 @@ class Artwork():
|
||||||
|
|
||||||
web_pass = {
|
web_pass = {
|
||||||
|
|
||||||
"jsonrpc": "2.0",
|
|
||||||
"id": 1,
|
|
||||||
"method": "Settings.GetSettingValue",
|
|
||||||
"params": {
|
|
||||||
|
|
||||||
"setting": "services.webserverpassword"
|
"setting": "services.webserverpassword"
|
||||||
}
|
}
|
||||||
}
|
result = get_setting_value.execute(web_pass)
|
||||||
result = xbmc.executeJSONRPC(json.dumps(web_pass))
|
|
||||||
result = json.loads(result)
|
|
||||||
try:
|
try:
|
||||||
self.xbmc_password = result['result']['value']
|
self.xbmc_password = result['result']['value']
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def fullTextureCacheSync(self):
|
def texture_cache_sync(self):
|
||||||
# This method will sync all Kodi artwork to textures13.db
|
# This method will sync all Kodi artwork to textures13.db
|
||||||
# and cache them locally. This takes diskspace!
|
# and cache them locally. This takes diskspace!
|
||||||
dialog = xbmcgui.Dialog()
|
if not dialog(type_="yesno",
|
||||||
|
heading="{emby}",
|
||||||
if not dialog.yesno(
|
|
||||||
heading=lang(29999),
|
|
||||||
line1=lang(33042)):
|
line1=lang(33042)):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -179,41 +140,36 @@ class Artwork():
|
||||||
pdialog.create(lang(29999), lang(33043))
|
pdialog.create(lang(29999), lang(33043))
|
||||||
|
|
||||||
# ask to rest all existing or not
|
# ask to rest all existing or not
|
||||||
if dialog.yesno(lang(29999), lang(33044)):
|
if dialog(type_="yesno", heading="{emby}", line1=lang(33044)):
|
||||||
log.info("Resetting all cache data first.")
|
log.info("Resetting all cache data first")
|
||||||
|
self._delete_cache()
|
||||||
# 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()
|
|
||||||
|
|
||||||
# Cache all entries in video DB
|
# Cache all entries in video DB
|
||||||
connection = kodiSQL('video')
|
self._cache_all_video_entries(pdialog)
|
||||||
cursor = connection.cursor()
|
# 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
|
cursor.execute("SELECT url FROM art WHERE media_type != 'actor'") # dont include actors
|
||||||
result = cursor.fetchall()
|
result = cursor.fetchall()
|
||||||
total = len(result)
|
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()
|
cursor.close()
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
|
@ -223,18 +179,19 @@ class Artwork():
|
||||||
break
|
break
|
||||||
|
|
||||||
percentage = int((float(count) / float(total))*100)
|
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))
|
pdialog.update(percentage, "%s %s" % (lang(33045), message))
|
||||||
self.cacheTexture(url[0])
|
self.cache_texture(url[0])
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
# Cache all entries in music DB
|
def _cache_all_music_entries(self, pdialog):
|
||||||
connection = kodiSQL('music')
|
|
||||||
cursor = connection.cursor()
|
conn = kodiSQL('music')
|
||||||
|
cursor = conn.cursor()
|
||||||
cursor.execute("SELECT url FROM art")
|
cursor.execute("SELECT url FROM art")
|
||||||
result = cursor.fetchall()
|
result = cursor.fetchall()
|
||||||
total = len(result)
|
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()
|
cursor.close()
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
|
@ -246,68 +203,84 @@ class Artwork():
|
||||||
percentage = int((float(count) / float(total))*100)
|
percentage = int((float(count) / float(total))*100)
|
||||||
message = "%s of %s" % (count, total)
|
message = "%s of %s" % (count, total)
|
||||||
pdialog.update(percentage, "%s %s" % (lang(33045), message))
|
pdialog.update(percentage, "%s %s" % (lang(33045), message))
|
||||||
self.cacheTexture(url[0])
|
self.cache_texture(url[0])
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
pdialog.update(100, "%s %s" % (lang(33046), len(self.imageCacheThreads)))
|
@classmethod
|
||||||
log.info("Waiting for all threads to exit")
|
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:
|
||||||
|
|
||||||
while len(self.imageCacheThreads):
|
if os.path.supports_unicode_filenames:
|
||||||
for thread in self.imageCacheThreads:
|
filename = os.path.join(path + directory.decode('utf-8'),
|
||||||
if thread.is_finished:
|
file_.decode('utf-8'))
|
||||||
self.imageCacheThreads.remove(thread)
|
else:
|
||||||
pdialog.update(100, "%s %s" % (lang(33046), len(self.imageCacheThreads)))
|
filename = os.path.join(path.encode('utf-8') + directory, file_)
|
||||||
log.info("Waiting for all threads to exit: %s" % len(self.imageCacheThreads))
|
|
||||||
xbmc.sleep(500)
|
|
||||||
|
|
||||||
pdialog.close()
|
xbmcvfs.delete(filename)
|
||||||
|
log.info("deleted: %s", filename)
|
||||||
|
|
||||||
def addWorkerImageCacheThread(self, url):
|
# 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:
|
while True:
|
||||||
# removed finished
|
# removed finished
|
||||||
for thread in self.imageCacheThreads:
|
for thread in self.image_cache_threads:
|
||||||
if thread.is_finished:
|
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
|
# add a new thread or wait and retry if we hit our limit
|
||||||
if len(self.imageCacheThreads) < self.imageCacheLimitThreads:
|
if len(self.image_cache_threads) < self.image_cache_limit:
|
||||||
newThread = image_cache_thread.ImageCacheThread()
|
|
||||||
newThread.set_url(self.double_urlencode(url))
|
new_thread = image_cache_thread.ImageCacheThread()
|
||||||
newThread.set_host(self.xbmc_host, self.xbmc_port)
|
new_thread.set_url(self._double_urlencode(url))
|
||||||
newThread.set_auth(self.xbmc_username, self.xbmc_password)
|
new_thread.set_host(self.xbmc_host, self.xbmc_port)
|
||||||
newThread.start()
|
new_thread.set_auth(self.xbmc_username, self.xbmc_password)
|
||||||
self.imageCacheThreads.append(newThread)
|
|
||||||
|
new_thread.start()
|
||||||
|
self.image_cache_threads.append(new_thread)
|
||||||
return
|
return
|
||||||
else:
|
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)
|
xbmc.sleep(50)
|
||||||
|
|
||||||
def cacheTexture(self, url):
|
def cache_texture(self, url):
|
||||||
# Cache a single image url to the texture cache
|
# Cache a single image url to the texture cache
|
||||||
if url and self.enableTextureCache:
|
if url and self.enable_texture_cache:
|
||||||
log.debug("Processing: %s" % url)
|
log.debug("Processing: %s", url)
|
||||||
|
|
||||||
if not self.imageCacheLimitThreads:
|
if not self.image_cache_limit:
|
||||||
# Add image to texture cache by simply calling it at the http endpoint
|
|
||||||
|
|
||||||
url = self.double_urlencode(url)
|
url = self._double_urlencode(url)
|
||||||
try: # Extreme short timeouts so we will have a exception.
|
try: # Add image to texture cache by simply calling it at the http endpoint
|
||||||
response = requests.head(
|
requests.head(url=("http://%s:%s/image/image://%s"
|
||||||
url=("http://%s:%s/image/image://%s"
|
|
||||||
% (self.xbmc_host, self.xbmc_port, url)),
|
% (self.xbmc_host, self.xbmc_port, url)),
|
||||||
auth=(self.xbmc_username, self.xbmc_password),
|
auth=(self.xbmc_username, self.xbmc_password),
|
||||||
timeout=(0.01, 0.01))
|
timeout=(0.01, 0.01))
|
||||||
# We don't need the result
|
except Exception: # We don't need the result
|
||||||
except: pass
|
pass
|
||||||
|
|
||||||
else:
|
else:
|
||||||
self.addWorkerImageCacheThread(url)
|
self._add_worker_image_thread(url)
|
||||||
|
|
||||||
|
def add_artwork(self, artwork, kodi_id, media_type, cursor):
|
||||||
def addArtwork(self, artwork, kodiId, mediaType, cursor):
|
|
||||||
# Kodi conversion table
|
# Kodi conversion table
|
||||||
kodiart = {
|
kodi_artwork = {
|
||||||
|
|
||||||
'Primary': ["thumb", "poster"],
|
'Primary': ["thumb", "poster"],
|
||||||
'Banner': "banner",
|
'Banner': "banner",
|
||||||
|
@ -318,15 +291,14 @@ class Artwork():
|
||||||
'Backdrop': "fanart",
|
'Backdrop': "fanart",
|
||||||
'BoxRear': "poster"
|
'BoxRear': "poster"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Artwork is a dictionary
|
# 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
|
# Backdrop entry is a list
|
||||||
# Process extra fanart for artwork downloader (fanart, fanart1, fanart2...)
|
# Process extra fanart for artwork downloader (fanart, fanart1, fanart2...)
|
||||||
backdrops = artwork[art]
|
backdrops = artwork[artwork_type]
|
||||||
backdropsNumber = len(backdrops)
|
backdrops_number = len(backdrops)
|
||||||
|
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
|
||||||
|
@ -336,10 +308,10 @@ class Artwork():
|
||||||
"AND media_type = ?",
|
"AND media_type = ?",
|
||||||
"AND type LIKE ?"
|
"AND type LIKE ?"
|
||||||
))
|
))
|
||||||
cursor.execute(query, (kodiId, mediaType, "fanart%",))
|
cursor.execute(query, (kodi_id, media_type, "fanart%",))
|
||||||
rows = cursor.fetchall()
|
rows = cursor.fetchall()
|
||||||
|
|
||||||
if len(rows) > backdropsNumber:
|
if len(rows) > backdrops_number:
|
||||||
# More backdrops in database. Delete extra fanart.
|
# More backdrops in database. Delete extra fanart.
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
|
||||||
|
@ -348,47 +320,40 @@ class Artwork():
|
||||||
"AND media_type = ?",
|
"AND media_type = ?",
|
||||||
"AND type LIKE ?"
|
"AND type LIKE ?"
|
||||||
))
|
))
|
||||||
cursor.execute(query, (kodiId, mediaType, "fanart_",))
|
cursor.execute(query, (kodi_id, media_type, "fanart_",))
|
||||||
|
|
||||||
# Process backdrops and extra fanart
|
# Process backdrops and extra fanart
|
||||||
index = ""
|
for index, backdrop in enumerate(backdrops):
|
||||||
for backdrop in backdrops:
|
|
||||||
self.addOrUpdateArt(
|
self.add_update_art(image_url=backdrop,
|
||||||
imageUrl=backdrop,
|
kodi_id=kodi_id,
|
||||||
kodiId=kodiId,
|
media_type=media_type,
|
||||||
mediaType=mediaType,
|
image_type=("fanart" if not index else "%s%s"
|
||||||
imageType="%s%s" % ("fanart", index),
|
% ("fanart", index)),
|
||||||
cursor=cursor)
|
cursor=cursor)
|
||||||
|
|
||||||
if backdropsNumber > 1:
|
elif artwork_type == 'Primary':
|
||||||
try: # Will only fail on the first try, str to int.
|
|
||||||
index += 1
|
|
||||||
except TypeError:
|
|
||||||
index = 1
|
|
||||||
|
|
||||||
elif art == "Primary":
|
|
||||||
# Primary art is processed as thumb and poster for Kodi.
|
# Primary art is processed as thumb and poster for Kodi.
|
||||||
for artType in kodiart[art]:
|
for art_type in kodi_artwork[artwork_type]:
|
||||||
self.addOrUpdateArt(
|
self.add_update_art(image_url=artwork[artwork_type],
|
||||||
imageUrl=artwork[art],
|
kodi_id=kodi_id,
|
||||||
kodiId=kodiId,
|
media_type=media_type,
|
||||||
mediaType=mediaType,
|
image_type=art_type,
|
||||||
imageType=artType,
|
|
||||||
cursor=cursor)
|
cursor=cursor)
|
||||||
|
|
||||||
elif kodiart.get(art):
|
elif artwork_type in kodi_artwork:
|
||||||
# Process the rest artwork type that Kodi can use
|
# Process the rest artwork type that Kodi can use
|
||||||
self.addOrUpdateArt(
|
self.add_update_art(image_url=artwork[artwork_type],
|
||||||
imageUrl=artwork[art],
|
kodi_id=kodi_id,
|
||||||
kodiId=kodiId,
|
media_type=media_type,
|
||||||
mediaType=mediaType,
|
image_type=kodi_artwork[artwork_type],
|
||||||
imageType=kodiart[art],
|
|
||||||
cursor=cursor)
|
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
|
# Possible that the imageurl is an empty string
|
||||||
if imageUrl:
|
if image_url:
|
||||||
cacheimage = False
|
|
||||||
|
cache_image = False
|
||||||
|
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
|
||||||
|
@ -398,13 +363,13 @@ class Artwork():
|
||||||
"AND media_type = ?",
|
"AND media_type = ?",
|
||||||
"AND type = ?"
|
"AND type = ?"
|
||||||
))
|
))
|
||||||
cursor.execute(query, (kodiId, mediaType, imageType,))
|
cursor.execute(query, (kodi_id, media_type, image_type,))
|
||||||
try: # Update the artwork
|
try: # Update the artwork
|
||||||
url = cursor.fetchone()[0]
|
url = cursor.fetchone()[0]
|
||||||
|
|
||||||
except TypeError: # Add the artwork
|
except TypeError: # Add the artwork
|
||||||
cacheimage = True
|
cache_image = True
|
||||||
log.debug("Adding Art Link for kodiId: %s (%s)" % (kodiId, imageUrl))
|
log.debug("Adding Art Link for kodiId: %s (%s)", kodi_id, image_url)
|
||||||
|
|
||||||
query = (
|
query = (
|
||||||
'''
|
'''
|
||||||
|
@ -413,20 +378,21 @@ class Artwork():
|
||||||
VALUES (?, ?, ?, ?)
|
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
|
else: # Only cache artwork if it changed
|
||||||
if url != imageUrl:
|
if url != image_url:
|
||||||
cacheimage = True
|
|
||||||
|
cache_image = True
|
||||||
|
|
||||||
# Only for the main backdrop, poster
|
# Only for the main backdrop, poster
|
||||||
if (window('emby_initialScan') != "true" and
|
if (window('emby_initialScan') != "true" and
|
||||||
imageType in ("fanart", "poster")):
|
image_type in ("fanart", "poster")):
|
||||||
# Delete current entry before updating with the new one
|
# 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)"
|
log.info("Updating Art url for %s kodiId: %s (%s) -> (%s)",
|
||||||
% (imageType, kodiId, url, imageUrl))
|
image_type, kodi_id, url, image_url)
|
||||||
|
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
|
||||||
|
@ -436,13 +402,13 @@ class Artwork():
|
||||||
"AND media_type = ?",
|
"AND media_type = ?",
|
||||||
"AND 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
|
# Cache fanart and poster in Kodi texture cache
|
||||||
if cacheimage and imageType in ("fanart", "poster"):
|
if cache_image and image_type in ("fanart", "poster"):
|
||||||
self.cacheTexture(imageUrl)
|
self.cache_texture(image_url)
|
||||||
|
|
||||||
def deleteArtwork(self, kodiId, mediaType, cursor):
|
def delete_artwork(self, kodi_id, media_type, cursor):
|
||||||
|
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
|
||||||
|
@ -451,85 +417,83 @@ class Artwork():
|
||||||
"WHERE media_id = ?",
|
"WHERE media_id = ?",
|
||||||
"AND media_type = ?"
|
"AND media_type = ?"
|
||||||
))
|
))
|
||||||
cursor.execute(query, (kodiId, mediaType,))
|
cursor.execute(query, (kodi_id, media_type,))
|
||||||
rows = cursor.fetchall()
|
rows = cursor.fetchall()
|
||||||
for row in rows:
|
for row in rows:
|
||||||
|
|
||||||
url = row[0]
|
url = row[0]
|
||||||
imageType = row[1]
|
image_type = row[1]
|
||||||
if imageType in ("poster", "fanart"):
|
if image_type in ("poster", "fanart"):
|
||||||
self.deleteCachedArtwork(url)
|
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
|
# Only necessary to remove and apply a new backdrop or poster
|
||||||
connection = kodiSQL('texture')
|
conn = kodiSQL('texture')
|
||||||
cursor = connection.cursor()
|
cursor = conn.cursor()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cursor.execute("SELECT cachedurl FROM texture WHERE url = ?", (url,))
|
cursor.execute("SELECT cachedurl FROM texture WHERE url = ?", (url,))
|
||||||
cachedurl = cursor.fetchone()[0]
|
cached_url = cursor.fetchone()[0]
|
||||||
|
|
||||||
except TypeError:
|
except TypeError:
|
||||||
log.info("Could not find cached url.")
|
log.info("Could not find cached url")
|
||||||
|
|
||||||
except OperationalError:
|
except OperationalError:
|
||||||
log.info("Database is locked. Skip deletion process.")
|
log.info("Database is locked. Skip deletion process.")
|
||||||
|
|
||||||
else: # Delete thumbnail as well as the entry
|
else: # Delete thumbnail as well as the entry
|
||||||
thumbnails = xbmc.translatePath("special://thumbnails/%s" % cachedurl).decode('utf-8')
|
thumbnails = xbmc.translatePath("special://thumbnails/%s", cached_url).decode('utf-8')
|
||||||
log.info("Deleting cached thumbnail: %s" % thumbnails)
|
log.info("Deleting cached thumbnail: %s", thumbnails)
|
||||||
xbmcvfs.delete(thumbnails)
|
xbmcvfs.delete(thumbnails)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cursor.execute("DELETE FROM texture WHERE url = ?", (url,))
|
cursor.execute("DELETE FROM texture WHERE url = ?", (url,))
|
||||||
connection.commit()
|
conn.commit()
|
||||||
except OperationalError:
|
except OperationalError:
|
||||||
log.debug("Issue deleting url from cache. Skipping.")
|
log.debug("Issue deleting url from cache. Skipping.")
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
cursor.close()
|
cursor.close()
|
||||||
|
|
||||||
def getPeopleArtwork(self, people):
|
def get_people_artwork(self, people):
|
||||||
# append imageurl if existing
|
# append imageurl if existing
|
||||||
for person in people:
|
for person in people:
|
||||||
|
|
||||||
personId = person['Id']
|
|
||||||
tag = person.get('PrimaryImageTag')
|
|
||||||
|
|
||||||
image = ""
|
image = ""
|
||||||
if tag:
|
person_id = person['Id']
|
||||||
|
|
||||||
|
if "PrimaryImageTag" in person:
|
||||||
image = (
|
image = (
|
||||||
"%s/emby/Items/%s/Images/Primary?"
|
"%s/emby/Items/%s/Images/Primary?"
|
||||||
"MaxWidth=400&MaxHeight=400&Index=0&Tag=%s"
|
"MaxWidth=400&MaxHeight=400&Index=0&Tag=%s"
|
||||||
% (self.server, personId, tag))
|
% (self.server, person_id, person['PrimaryImageTag']))
|
||||||
|
|
||||||
person['imageurl'] = image
|
person['imageurl'] = image
|
||||||
|
|
||||||
return people
|
return people
|
||||||
|
|
||||||
def getUserArtwork(self, itemId, itemType):
|
def get_user_artwork(self, item_id, item_type):
|
||||||
# Load user information set by UserClient
|
# Load user information set by UserClient
|
||||||
image = ("%s/emby/Users/%s/Images/%s?Format=original"
|
return "%s/emby/Users/%s/Images/%s?Format=original" % (self.server, item_id, item_type)
|
||||||
% (self.server, itemId, itemType))
|
|
||||||
return image
|
|
||||||
|
|
||||||
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']
|
artworks = item['ImageTags']
|
||||||
backdrops = item.get('BackdropImageTags', [])
|
backdrops = item.get('BackdropImageTags', [])
|
||||||
|
|
||||||
maxHeight = 10000
|
max_height = 10000
|
||||||
maxWidth = 10000
|
max_width = 10000
|
||||||
customquery = ""
|
custom_query = ""
|
||||||
|
|
||||||
if settings('compressArt') == "true":
|
if settings('compressArt') == "true":
|
||||||
customquery = "&Quality=90"
|
custom_query = "&Quality=90"
|
||||||
|
|
||||||
if settings('enableCoverArt') == "false":
|
if settings('enableCoverArt') == "false":
|
||||||
customquery += "&EnableImageEnhancers=false"
|
custom_query += "&EnableImageEnhancers=false"
|
||||||
|
|
||||||
allartworks = {
|
all_artwork = {
|
||||||
|
|
||||||
'Primary': "",
|
'Primary': "",
|
||||||
'Art': "",
|
'Art': "",
|
||||||
|
@ -540,71 +504,52 @@ class Artwork():
|
||||||
'Backdrop': []
|
'Backdrop': []
|
||||||
}
|
}
|
||||||
|
|
||||||
# Process backdrops
|
def get_backdrops(backdrops):
|
||||||
|
|
||||||
for index, tag in enumerate(backdrops):
|
for index, tag in enumerate(backdrops):
|
||||||
artwork = (
|
artwork = ("%s/emby/Items/%s/Images/Backdrop/%s?"
|
||||||
"%s/emby/Items/%s/Images/Backdrop/%s?"
|
|
||||||
"MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s"
|
"MaxWidth=%s&MaxHeight=%s&Format=original&Tag=%s%s"
|
||||||
% (self.server, itemid, index, maxWidth, maxHeight, tag, customquery))
|
% (self.server, item_id, index, max_width, max_height,
|
||||||
allartworks['Backdrop'].append(artwork)
|
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
|
||||||
|
get_backdrops(backdrops)
|
||||||
|
|
||||||
# Process the rest of the artwork
|
# Process the rest of the artwork
|
||||||
for art in artworks:
|
for artwork in artworks:
|
||||||
# Filter backcover
|
# Filter backcover
|
||||||
if art != "BoxRear":
|
if artwork != "BoxRear":
|
||||||
tag = artworks[art]
|
get_artwork(artwork, artworks[artwork])
|
||||||
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
|
|
||||||
|
|
||||||
# Process parent items if the main item is missing artwork
|
# Process parent items if the main item is missing artwork
|
||||||
if parentInfo:
|
if parent_info:
|
||||||
|
|
||||||
# Process parent backdrops
|
# Process parent backdrops
|
||||||
if not allartworks['Backdrop']:
|
if not all_artwork['Backdrop']:
|
||||||
|
|
||||||
parentId = item.get('ParentBackdropItemId')
|
if 'ParentBackdropItemId' in item:
|
||||||
if parentId:
|
# If there is a parent_id, go through the parent backdrop list
|
||||||
# If there is a parentId, go through the parent backdrop list
|
get_backdrops(item['ParentBackdropImageTags'])
|
||||||
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)
|
|
||||||
|
|
||||||
# Process the rest of the artwork
|
# Process the rest of the artwork
|
||||||
parentartwork = ['Logo', 'Art', 'Thumb']
|
for parent_artwork in ('Logo', 'Art', 'Thumb'):
|
||||||
for parentart in parentartwork:
|
|
||||||
|
|
||||||
if not allartworks[parentart]:
|
if not all_artwork[parent_artwork]:
|
||||||
|
|
||||||
parentId = item.get('Parent%sItemId' % parentart)
|
if 'Parent%sItemId' % parent_artwork in item:
|
||||||
if parentId:
|
get_artwork(parent_artwork, item['Parent%sImageTag' % parent_artwork])
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
# Parent album works a bit differently
|
# Parent album works a bit differently
|
||||||
if not allartworks['Primary']:
|
if not all_artwork['Primary']:
|
||||||
|
|
||||||
parentId = item.get('AlbumId')
|
if 'AlbumId' in item and 'AlbumPrimaryImageTag' in item:
|
||||||
if parentId and item.get('AlbumPrimaryImageTag'):
|
get_artwork('Primary', item['AlbumPrimaryImageTag'])
|
||||||
|
|
||||||
parentTag = item['AlbumPrimaryImageTag']
|
return all_artwork
|
||||||
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
|
|
||||||
|
|
|
@ -191,7 +191,7 @@ class Embydb_Functions():
|
||||||
self.embycursor.execute(query, (parentid, mediatype,))
|
self.embycursor.execute(query, (parentid, mediatype,))
|
||||||
return self.embycursor.fetchall()
|
return self.embycursor.fetchall()
|
||||||
|
|
||||||
def getChecksum(self, mediatype):
|
def get_checksum(self, mediatype):
|
||||||
|
|
||||||
query = ' '.join((
|
query = ' '.join((
|
||||||
|
|
||||||
|
|
|
@ -319,7 +319,7 @@ def addUser():
|
||||||
url = "{server}/emby/Users/%s?format=json" % userid
|
url = "{server}/emby/Users/%s?format=json" % userid
|
||||||
result = doUtils.downloadUrl(url)
|
result = doUtils.downloadUrl(url)
|
||||||
window('EmbyAdditionalUserImage.%s' % count,
|
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))
|
window('EmbyAdditionalUserPosition.%s' % userid, value=str(count))
|
||||||
count +=1
|
count +=1
|
||||||
|
|
||||||
|
@ -608,7 +608,7 @@ def createListItemFromEmbyItem(item,art=artwork.Artwork(),doUtils=downloadutils.
|
||||||
|
|
||||||
li.setProperty("embyid",itemid)
|
li.setProperty("embyid",itemid)
|
||||||
|
|
||||||
allart = art.getAllArtwork(item)
|
allart = art.get_all_artwork(item)
|
||||||
|
|
||||||
if item["Type"] == "Photo":
|
if item["Type"] == "Photo":
|
||||||
#listitem setup for pictures...
|
#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.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.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.setThumbnailImage(img_path)
|
||||||
li.setProperty("plot",API.getOverview())
|
li.setProperty("plot",API.get_overview())
|
||||||
li.setIconImage('DefaultPicture.png')
|
li.setIconImage('DefaultPicture.png')
|
||||||
else:
|
else:
|
||||||
#normal video items
|
#normal video items
|
||||||
li.setProperty('IsPlayable', 'true')
|
li.setProperty('IsPlayable', 'true')
|
||||||
path = "%s?id=%s&mode=play" % (sys.argv[0], item.get("Id"))
|
path = "%s?id=%s&mode=play" % (sys.argv[0], item.get("Id"))
|
||||||
li.setProperty("path",path)
|
li.setProperty("path",path)
|
||||||
genre = API.getGenres()
|
genre = API.get_genres()
|
||||||
overlay = 0
|
overlay = 0
|
||||||
userdata = API.getUserData()
|
userdata = API.get_userdata()
|
||||||
runtime = item.get("RunTimeTicks",0)/ 10000000.0
|
runtime = item.get("RunTimeTicks",0)/ 10000000.0
|
||||||
seektime = userdata['Resume']
|
seektime = userdata['Resume']
|
||||||
if seektime:
|
if seektime:
|
||||||
|
@ -655,7 +655,7 @@ def createListItemFromEmbyItem(item,art=artwork.Artwork(),doUtils=downloadutils.
|
||||||
'genre': genre,
|
'genre': genre,
|
||||||
'playcount': str(playcount),
|
'playcount': str(playcount),
|
||||||
'title': title,
|
'title': title,
|
||||||
'plot': API.getOverview(),
|
'plot': API.get_overview(),
|
||||||
'Overlay': str(overlay),
|
'Overlay': str(overlay),
|
||||||
'duration': runtime
|
'duration': runtime
|
||||||
}
|
}
|
||||||
|
@ -672,7 +672,7 @@ def createListItemFromEmbyItem(item,art=artwork.Artwork(),doUtils=downloadutils.
|
||||||
else:
|
else:
|
||||||
pbutils.PlaybackUtils(item).setArtwork(li)
|
pbutils.PlaybackUtils(item).setArtwork(li)
|
||||||
|
|
||||||
mediastreams = API.getMediaStreams()
|
mediastreams = API.get_media_streams()
|
||||||
videostreamFound = False
|
videostreamFound = False
|
||||||
if mediastreams:
|
if mediastreams:
|
||||||
for key, value in mediastreams.iteritems():
|
for key, value in mediastreams.iteritems():
|
||||||
|
@ -1084,7 +1084,7 @@ def getExtraFanArt(embyId,embyPath):
|
||||||
xbmcvfs.mkdirs(fanartDir)
|
xbmcvfs.mkdirs(fanartDir)
|
||||||
item = emby.getItem(embyId)
|
item = emby.getItem(embyId)
|
||||||
if item:
|
if item:
|
||||||
backdrops = art.getAllArtwork(item)['Backdrop']
|
backdrops = art.get_all_artwork(item)['Backdrop']
|
||||||
tags = item['BackdropImageTags']
|
tags = item['BackdropImageTags']
|
||||||
count = 0
|
count = 0
|
||||||
for backdrop in backdrops:
|
for backdrop in backdrops:
|
||||||
|
|
|
@ -307,31 +307,31 @@ class Movies(Items):
|
||||||
log.debug("View tag found: %s" % viewtag)
|
log.debug("View tag found: %s" % viewtag)
|
||||||
|
|
||||||
# fileId information
|
# fileId information
|
||||||
checksum = API.getChecksum()
|
checksum = API.get_checksum()
|
||||||
dateadded = API.getDateCreated()
|
dateadded = API.get_date_created()
|
||||||
userdata = API.getUserData()
|
userdata = API.get_userdata()
|
||||||
playcount = userdata['PlayCount']
|
playcount = userdata['PlayCount']
|
||||||
dateplayed = userdata['LastPlayedDate']
|
dateplayed = userdata['LastPlayedDate']
|
||||||
|
|
||||||
# item details
|
# item details
|
||||||
people = API.getPeople()
|
people = API.get_people()
|
||||||
writer = " / ".join(people['Writer'])
|
writer = " / ".join(people['Writer'])
|
||||||
director = " / ".join(people['Director'])
|
director = " / ".join(people['Director'])
|
||||||
genres = item['Genres']
|
genres = item['Genres']
|
||||||
title = item['Name']
|
title = item['Name']
|
||||||
plot = API.getOverview()
|
plot = API.get_overview()
|
||||||
shortplot = item.get('ShortOverview')
|
shortplot = item.get('ShortOverview')
|
||||||
tagline = API.getTagline()
|
tagline = API.get_tagline()
|
||||||
votecount = item.get('VoteCount')
|
votecount = item.get('VoteCount')
|
||||||
rating = item.get('CommunityRating')
|
rating = item.get('CommunityRating')
|
||||||
year = item.get('ProductionYear')
|
year = item.get('ProductionYear')
|
||||||
imdb = API.getProvider('Imdb')
|
imdb = API.get_provider('Imdb')
|
||||||
sorttitle = item['SortName']
|
sorttitle = item['SortName']
|
||||||
runtime = API.getRuntime()
|
runtime = API.get_runtime()
|
||||||
mpaa = API.getMpaa()
|
mpaa = API.get_mpaa()
|
||||||
genre = " / ".join(genres)
|
genre = " / ".join(genres)
|
||||||
country = API.getCountry()
|
country = API.get_country()
|
||||||
studios = API.getStudios()
|
studios = API.get_studios()
|
||||||
try:
|
try:
|
||||||
studio = studios[0]
|
studio = studios[0]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
@ -366,7 +366,7 @@ class Movies(Items):
|
||||||
|
|
||||||
|
|
||||||
##### GET THE FILE AND PATH #####
|
##### GET THE FILE AND PATH #####
|
||||||
playurl = API.getFilePath()
|
playurl = API.get_file_path()
|
||||||
|
|
||||||
if "\\" in playurl:
|
if "\\" in playurl:
|
||||||
# Local path
|
# Local path
|
||||||
|
@ -461,14 +461,14 @@ class Movies(Items):
|
||||||
# Process countries
|
# Process countries
|
||||||
self.kodi_db.addCountries(movieid, item['ProductionLocations'], "movie")
|
self.kodi_db.addCountries(movieid, item['ProductionLocations'], "movie")
|
||||||
# Process cast
|
# Process cast
|
||||||
people = artwork.getPeopleArtwork(item['People'])
|
people = artwork.get_people_artwork(item['People'])
|
||||||
self.kodi_db.addPeople(movieid, people, "movie")
|
self.kodi_db.addPeople(movieid, people, "movie")
|
||||||
# Process genres
|
# Process genres
|
||||||
self.kodi_db.addGenres(movieid, genres, "movie")
|
self.kodi_db.addGenres(movieid, genres, "movie")
|
||||||
# Process artwork
|
# Process artwork
|
||||||
artwork.addArtwork(artwork.getAllArtwork(item), movieid, "movie", kodicursor)
|
artwork.add_artwork(artwork.get_all_artwork(item), movieid, "movie", kodicursor)
|
||||||
# Process stream details
|
# Process stream details
|
||||||
streams = API.getMediaStreams()
|
streams = API.get_media_streams()
|
||||||
self.kodi_db.addStreams(fileid, streams, runtime)
|
self.kodi_db.addStreams(fileid, streams, runtime)
|
||||||
# Process studios
|
# Process studios
|
||||||
self.kodi_db.addStudios(movieid, studios, "movie")
|
self.kodi_db.addStudios(movieid, studios, "movie")
|
||||||
|
@ -479,7 +479,7 @@ class Movies(Items):
|
||||||
tags.append("Favorite movies")
|
tags.append("Favorite movies")
|
||||||
self.kodi_db.addTags(movieid, tags, "movie")
|
self.kodi_db.addTags(movieid, tags, "movie")
|
||||||
# Process playstates
|
# Process playstates
|
||||||
resume = API.adjustResume(userdata['Resume'])
|
resume = API.adjust_resume(userdata['Resume'])
|
||||||
total = round(float(runtime), 6)
|
total = round(float(runtime), 6)
|
||||||
self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
|
self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
|
||||||
|
|
||||||
|
@ -500,7 +500,7 @@ class Movies(Items):
|
||||||
setid = self.kodi_db.createBoxset(title)
|
setid = self.kodi_db.createBoxset(title)
|
||||||
|
|
||||||
# Process artwork
|
# 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
|
# Process movies inside boxset
|
||||||
current_movies = emby_db.getItemId_byParentId(setid, "movie")
|
current_movies = emby_db.getItemId_byParentId(setid, "movie")
|
||||||
|
@ -556,9 +556,9 @@ class Movies(Items):
|
||||||
|
|
||||||
# Get emby information
|
# Get emby information
|
||||||
itemid = item['Id']
|
itemid = item['Id']
|
||||||
checksum = API.getChecksum()
|
checksum = API.get_checksum()
|
||||||
userdata = API.getUserData()
|
userdata = API.get_userdata()
|
||||||
runtime = API.getRuntime()
|
runtime = API.get_runtime()
|
||||||
|
|
||||||
# Get Kodi information
|
# Get Kodi information
|
||||||
emby_dbitem = emby_db.getItem_byId(itemid)
|
emby_dbitem = emby_db.getItem_byId(itemid)
|
||||||
|
@ -578,7 +578,7 @@ class Movies(Items):
|
||||||
# Process playstates
|
# Process playstates
|
||||||
playcount = userdata['PlayCount']
|
playcount = userdata['PlayCount']
|
||||||
dateplayed = userdata['LastPlayedDate']
|
dateplayed = userdata['LastPlayedDate']
|
||||||
resume = API.adjustResume(userdata['Resume'])
|
resume = API.adjust_resume(userdata['Resume'])
|
||||||
total = round(float(runtime), 6)
|
total = round(float(runtime), 6)
|
||||||
|
|
||||||
log.debug("%s New resume point: %s" % (itemid, resume))
|
log.debug("%s New resume point: %s" % (itemid, resume))
|
||||||
|
@ -604,7 +604,7 @@ class Movies(Items):
|
||||||
# Remove the emby reference
|
# Remove the emby reference
|
||||||
emby_db.removeItem(itemid)
|
emby_db.removeItem(itemid)
|
||||||
# Remove artwork
|
# Remove artwork
|
||||||
artwork.deleteArtwork(kodiid, mediatype, kodicursor)
|
artwork.delete_artwork(kodiid, mediatype, kodicursor)
|
||||||
|
|
||||||
if mediatype == "movie":
|
if mediatype == "movie":
|
||||||
# Delete kodi movie and file
|
# Delete kodi movie and file
|
||||||
|
@ -693,30 +693,30 @@ class MusicVideos(Items):
|
||||||
log.debug("View tag found: %s" % viewtag)
|
log.debug("View tag found: %s" % viewtag)
|
||||||
|
|
||||||
# fileId information
|
# fileId information
|
||||||
checksum = API.getChecksum()
|
checksum = API.get_checksum()
|
||||||
dateadded = API.getDateCreated()
|
dateadded = API.get_date_created()
|
||||||
userdata = API.getUserData()
|
userdata = API.get_userdata()
|
||||||
playcount = userdata['PlayCount']
|
playcount = userdata['PlayCount']
|
||||||
dateplayed = userdata['LastPlayedDate']
|
dateplayed = userdata['LastPlayedDate']
|
||||||
|
|
||||||
# item details
|
# item details
|
||||||
runtime = API.getRuntime()
|
runtime = API.get_runtime()
|
||||||
plot = API.getOverview()
|
plot = API.get_overview()
|
||||||
title = item['Name']
|
title = item['Name']
|
||||||
year = item.get('ProductionYear')
|
year = item.get('ProductionYear')
|
||||||
genres = item['Genres']
|
genres = item['Genres']
|
||||||
genre = " / ".join(genres)
|
genre = " / ".join(genres)
|
||||||
studios = API.getStudios()
|
studios = API.get_studios()
|
||||||
studio = " / ".join(studios)
|
studio = " / ".join(studios)
|
||||||
artist = " / ".join(item.get('Artists'))
|
artist = " / ".join(item.get('Artists'))
|
||||||
album = item.get('Album')
|
album = item.get('Album')
|
||||||
track = item.get('Track')
|
track = item.get('Track')
|
||||||
people = API.getPeople()
|
people = API.get_people()
|
||||||
director = " / ".join(people['Director'])
|
director = " / ".join(people['Director'])
|
||||||
|
|
||||||
|
|
||||||
##### GET THE FILE AND PATH #####
|
##### GET THE FILE AND PATH #####
|
||||||
playurl = API.getFilePath()
|
playurl = API.get_file_path()
|
||||||
|
|
||||||
if "\\" in playurl:
|
if "\\" in playurl:
|
||||||
# Local path
|
# Local path
|
||||||
|
@ -833,14 +833,14 @@ class MusicVideos(Items):
|
||||||
for artist in artists:
|
for artist in artists:
|
||||||
artist['Type'] = "Artist"
|
artist['Type'] = "Artist"
|
||||||
people.extend(artists)
|
people.extend(artists)
|
||||||
people = artwork.getPeopleArtwork(people)
|
people = artwork.get_people_artwork(people)
|
||||||
self.kodi_db.addPeople(mvideoid, people, "musicvideo")
|
self.kodi_db.addPeople(mvideoid, people, "musicvideo")
|
||||||
# Process genres
|
# Process genres
|
||||||
self.kodi_db.addGenres(mvideoid, genres, "musicvideo")
|
self.kodi_db.addGenres(mvideoid, genres, "musicvideo")
|
||||||
# Process artwork
|
# Process artwork
|
||||||
artwork.addArtwork(artwork.getAllArtwork(item), mvideoid, "musicvideo", kodicursor)
|
artwork.add_artwork(artwork.get_all_artwork(item), mvideoid, "musicvideo", kodicursor)
|
||||||
# Process stream details
|
# Process stream details
|
||||||
streams = API.getMediaStreams()
|
streams = API.get_media_streams()
|
||||||
self.kodi_db.addStreams(fileid, streams, runtime)
|
self.kodi_db.addStreams(fileid, streams, runtime)
|
||||||
# Process studios
|
# Process studios
|
||||||
self.kodi_db.addStudios(mvideoid, studios, "musicvideo")
|
self.kodi_db.addStudios(mvideoid, studios, "musicvideo")
|
||||||
|
@ -851,7 +851,7 @@ class MusicVideos(Items):
|
||||||
tags.append("Favorite musicvideos")
|
tags.append("Favorite musicvideos")
|
||||||
self.kodi_db.addTags(mvideoid, tags, "musicvideo")
|
self.kodi_db.addTags(mvideoid, tags, "musicvideo")
|
||||||
# Process playstates
|
# Process playstates
|
||||||
resume = API.adjustResume(userdata['Resume'])
|
resume = API.adjust_resume(userdata['Resume'])
|
||||||
total = round(float(runtime), 6)
|
total = round(float(runtime), 6)
|
||||||
self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
|
self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
|
||||||
|
|
||||||
|
@ -863,9 +863,9 @@ class MusicVideos(Items):
|
||||||
|
|
||||||
# Get emby information
|
# Get emby information
|
||||||
itemid = item['Id']
|
itemid = item['Id']
|
||||||
checksum = API.getChecksum()
|
checksum = API.get_checksum()
|
||||||
userdata = API.getUserData()
|
userdata = API.get_userdata()
|
||||||
runtime = API.getRuntime()
|
runtime = API.get_runtime()
|
||||||
|
|
||||||
# Get Kodi information
|
# Get Kodi information
|
||||||
emby_dbitem = emby_db.getItem_byId(itemid)
|
emby_dbitem = emby_db.getItem_byId(itemid)
|
||||||
|
@ -887,7 +887,7 @@ class MusicVideos(Items):
|
||||||
# Process playstates
|
# Process playstates
|
||||||
playcount = userdata['PlayCount']
|
playcount = userdata['PlayCount']
|
||||||
dateplayed = userdata['LastPlayedDate']
|
dateplayed = userdata['LastPlayedDate']
|
||||||
resume = API.adjustResume(userdata['Resume'])
|
resume = API.adjust_resume(userdata['Resume'])
|
||||||
total = round(float(runtime), 6)
|
total = round(float(runtime), 6)
|
||||||
|
|
||||||
self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
|
self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
|
||||||
|
@ -922,7 +922,7 @@ class MusicVideos(Items):
|
||||||
url = row[0]
|
url = row[0]
|
||||||
imagetype = row[1]
|
imagetype = row[1]
|
||||||
if imagetype in ("poster", "fanart"):
|
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 musicvideo WHERE idMVideo = ?", (mvideoid,))
|
||||||
kodicursor.execute("DELETE FROM files WHERE idFile = ?", (fileid,))
|
kodicursor.execute("DELETE FROM files WHERE idFile = ?", (fileid,))
|
||||||
|
@ -1033,28 +1033,28 @@ class TVShows(Items):
|
||||||
log.debug("View tag found: %s" % viewtag)
|
log.debug("View tag found: %s" % viewtag)
|
||||||
|
|
||||||
# fileId information
|
# fileId information
|
||||||
checksum = API.getChecksum()
|
checksum = API.get_checksum()
|
||||||
dateadded = API.getDateCreated()
|
dateadded = API.get_date_created()
|
||||||
userdata = API.getUserData()
|
userdata = API.get_userdata()
|
||||||
playcount = userdata['PlayCount']
|
playcount = userdata['PlayCount']
|
||||||
dateplayed = userdata['LastPlayedDate']
|
dateplayed = userdata['LastPlayedDate']
|
||||||
|
|
||||||
# item details
|
# item details
|
||||||
genres = item['Genres']
|
genres = item['Genres']
|
||||||
title = item['Name']
|
title = item['Name']
|
||||||
plot = API.getOverview()
|
plot = API.get_overview()
|
||||||
rating = item.get('CommunityRating')
|
rating = item.get('CommunityRating')
|
||||||
premieredate = API.getPremiereDate()
|
premieredate = API.get_premiere_date()
|
||||||
tvdb = API.getProvider('Tvdb')
|
tvdb = API.get_provider('Tvdb')
|
||||||
sorttitle = item['SortName']
|
sorttitle = item['SortName']
|
||||||
mpaa = API.getMpaa()
|
mpaa = API.get_mpaa()
|
||||||
genre = " / ".join(genres)
|
genre = " / ".join(genres)
|
||||||
studios = API.getStudios()
|
studios = API.get_studios()
|
||||||
studio = " / ".join(studios)
|
studio = " / ".join(studios)
|
||||||
|
|
||||||
|
|
||||||
##### GET THE FILE AND PATH #####
|
##### GET THE FILE AND PATH #####
|
||||||
playurl = API.getFilePath()
|
playurl = API.get_file_path()
|
||||||
|
|
||||||
if self.directpath:
|
if self.directpath:
|
||||||
# Direct paths is set the Kodi way
|
# Direct paths is set the Kodi way
|
||||||
|
@ -1142,12 +1142,12 @@ class TVShows(Items):
|
||||||
kodicursor.execute(query, (path, None, None, 1, pathid))
|
kodicursor.execute(query, (path, None, None, 1, pathid))
|
||||||
|
|
||||||
# Process cast
|
# Process cast
|
||||||
people = artwork.getPeopleArtwork(item['People'])
|
people = artwork.get_people_artwork(item['People'])
|
||||||
self.kodi_db.addPeople(showid, people, "tvshow")
|
self.kodi_db.addPeople(showid, people, "tvshow")
|
||||||
# Process genres
|
# Process genres
|
||||||
self.kodi_db.addGenres(showid, genres, "tvshow")
|
self.kodi_db.addGenres(showid, genres, "tvshow")
|
||||||
# Process artwork
|
# Process artwork
|
||||||
artwork.addArtwork(artwork.getAllArtwork(item), showid, "tvshow", kodicursor)
|
artwork.add_artwork(artwork.get_all_artwork(item), showid, "tvshow", kodicursor)
|
||||||
# Process studios
|
# Process studios
|
||||||
self.kodi_db.addStudios(showid, studios, "tvshow")
|
self.kodi_db.addStudios(showid, studios, "tvshow")
|
||||||
# Process tags: view, emby tags
|
# Process tags: view, emby tags
|
||||||
|
@ -1164,7 +1164,7 @@ class TVShows(Items):
|
||||||
# Finally, refresh the all season entry
|
# Finally, refresh the all season entry
|
||||||
seasonid = self.kodi_db.addSeason(showid, -1)
|
seasonid = self.kodi_db.addSeason(showid, -1)
|
||||||
# Process artwork
|
# Process artwork
|
||||||
artwork.addArtwork(artwork.getAllArtwork(item), seasonid, "season", kodicursor)
|
artwork.add_artwork(artwork.get_all_artwork(item), seasonid, "season", kodicursor)
|
||||||
|
|
||||||
if force_episodes:
|
if force_episodes:
|
||||||
# We needed to recreate the show entry. Re-add episodes now.
|
# 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)
|
emby_db.addReference(item['Id'], seasonid, "Season", "season", parentid=showid)
|
||||||
|
|
||||||
# Process artwork
|
# 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):
|
def add_updateEpisode(self, item):
|
||||||
# Process single episode
|
# Process single episode
|
||||||
|
@ -1225,7 +1225,7 @@ class TVShows(Items):
|
||||||
|
|
||||||
except TypeError:
|
except TypeError:
|
||||||
update_item = False
|
update_item = False
|
||||||
log.info("episodeid: %s not found." % itemid)
|
log.debug("episodeid: %s not found." % itemid)
|
||||||
# episodeid
|
# episodeid
|
||||||
kodicursor.execute("select coalesce(max(idEpisode),0) from episode")
|
kodicursor.execute("select coalesce(max(idEpisode),0) from episode")
|
||||||
episodeid = kodicursor.fetchone()[0] + 1
|
episodeid = kodicursor.fetchone()[0] + 1
|
||||||
|
@ -1242,21 +1242,21 @@ class TVShows(Items):
|
||||||
log.info("episodeid: %s missing from Kodi, repairing the entry." % episodeid)
|
log.info("episodeid: %s missing from Kodi, repairing the entry." % episodeid)
|
||||||
|
|
||||||
# fileId information
|
# fileId information
|
||||||
checksum = API.getChecksum()
|
checksum = API.get_checksum()
|
||||||
dateadded = API.getDateCreated()
|
dateadded = API.get_date_created()
|
||||||
userdata = API.getUserData()
|
userdata = API.get_userdata()
|
||||||
playcount = userdata['PlayCount']
|
playcount = userdata['PlayCount']
|
||||||
dateplayed = userdata['LastPlayedDate']
|
dateplayed = userdata['LastPlayedDate']
|
||||||
|
|
||||||
# item details
|
# item details
|
||||||
people = API.getPeople()
|
people = API.get_people()
|
||||||
writer = " / ".join(people['Writer'])
|
writer = " / ".join(people['Writer'])
|
||||||
director = " / ".join(people['Director'])
|
director = " / ".join(people['Director'])
|
||||||
title = item['Name']
|
title = item['Name']
|
||||||
plot = API.getOverview()
|
plot = API.get_overview()
|
||||||
rating = item.get('CommunityRating')
|
rating = item.get('CommunityRating')
|
||||||
runtime = API.getRuntime()
|
runtime = API.get_runtime()
|
||||||
premieredate = API.getPremiereDate()
|
premieredate = API.get_premiere_date()
|
||||||
|
|
||||||
# episode details
|
# episode details
|
||||||
try:
|
try:
|
||||||
|
@ -1308,7 +1308,7 @@ class TVShows(Items):
|
||||||
|
|
||||||
|
|
||||||
##### GET THE FILE AND PATH #####
|
##### GET THE FILE AND PATH #####
|
||||||
playurl = API.getFilePath()
|
playurl = API.get_file_path()
|
||||||
|
|
||||||
if "\\" in playurl:
|
if "\\" in playurl:
|
||||||
# Local path
|
# Local path
|
||||||
|
@ -1431,16 +1431,16 @@ class TVShows(Items):
|
||||||
kodicursor.execute(query, (pathid, filename, dateadded, fileid))
|
kodicursor.execute(query, (pathid, filename, dateadded, fileid))
|
||||||
|
|
||||||
# Process cast
|
# Process cast
|
||||||
people = artwork.getPeopleArtwork(item['People'])
|
people = artwork.get_people_artwork(item['People'])
|
||||||
self.kodi_db.addPeople(episodeid, people, "episode")
|
self.kodi_db.addPeople(episodeid, people, "episode")
|
||||||
# Process artwork
|
# Process artwork
|
||||||
artworks = artwork.getAllArtwork(item)
|
artworks = artwork.get_all_artwork(item)
|
||||||
artwork.addOrUpdateArt(artworks['Primary'], episodeid, "episode", "thumb", kodicursor)
|
artwork.add_update_art(artworks['Primary'], episodeid, "episode", "thumb", kodicursor)
|
||||||
# Process stream details
|
# Process stream details
|
||||||
streams = API.getMediaStreams()
|
streams = API.get_media_streams()
|
||||||
self.kodi_db.addStreams(fileid, streams, runtime)
|
self.kodi_db.addStreams(fileid, streams, runtime)
|
||||||
# Process playstates
|
# Process playstates
|
||||||
resume = API.adjustResume(userdata['Resume'])
|
resume = API.adjust_resume(userdata['Resume'])
|
||||||
total = round(float(runtime), 6)
|
total = round(float(runtime), 6)
|
||||||
self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
|
self.kodi_db.addPlaystate(fileid, resume, total, playcount, dateplayed)
|
||||||
if not self.directpath and resume:
|
if not self.directpath and resume:
|
||||||
|
@ -1464,10 +1464,10 @@ class TVShows(Items):
|
||||||
|
|
||||||
# Get emby information
|
# Get emby information
|
||||||
itemid = item['Id']
|
itemid = item['Id']
|
||||||
checksum = API.getChecksum()
|
checksum = API.get_checksum()
|
||||||
userdata = API.getUserData()
|
userdata = API.get_userdata()
|
||||||
runtime = API.getRuntime()
|
runtime = API.get_runtime()
|
||||||
dateadded = API.getDateCreated()
|
dateadded = API.get_date_created()
|
||||||
|
|
||||||
# Get Kodi information
|
# Get Kodi information
|
||||||
emby_dbitem = emby_db.getItem_byId(itemid)
|
emby_dbitem = emby_db.getItem_byId(itemid)
|
||||||
|
@ -1491,7 +1491,7 @@ class TVShows(Items):
|
||||||
# Process playstates
|
# Process playstates
|
||||||
playcount = userdata['PlayCount']
|
playcount = userdata['PlayCount']
|
||||||
dateplayed = userdata['LastPlayedDate']
|
dateplayed = userdata['LastPlayedDate']
|
||||||
resume = API.adjustResume(userdata['Resume'])
|
resume = API.adjust_resume(userdata['Resume'])
|
||||||
total = round(float(runtime), 6)
|
total = round(float(runtime), 6)
|
||||||
|
|
||||||
log.debug("%s New resume point: %s" % (itemid, resume))
|
log.debug("%s New resume point: %s" % (itemid, resume))
|
||||||
|
@ -1627,7 +1627,7 @@ class TVShows(Items):
|
||||||
def removeShow(self, kodiid):
|
def removeShow(self, kodiid):
|
||||||
|
|
||||||
kodicursor = self.kodicursor
|
kodicursor = self.kodicursor
|
||||||
self.artwork.deleteArtwork(kodiid, "tvshow", kodicursor)
|
self.artwork.delete_artwork(kodiid, "tvshow", kodicursor)
|
||||||
kodicursor.execute("DELETE FROM tvshow WHERE idShow = ?", (kodiid,))
|
kodicursor.execute("DELETE FROM tvshow WHERE idShow = ?", (kodiid,))
|
||||||
log.debug("Removed tvshow: %s." % kodiid)
|
log.debug("Removed tvshow: %s." % kodiid)
|
||||||
|
|
||||||
|
@ -1635,7 +1635,7 @@ class TVShows(Items):
|
||||||
|
|
||||||
kodicursor = self.kodicursor
|
kodicursor = self.kodicursor
|
||||||
|
|
||||||
self.artwork.deleteArtwork(kodiid, "season", kodicursor)
|
self.artwork.delete_artwork(kodiid, "season", kodicursor)
|
||||||
kodicursor.execute("DELETE FROM seasons WHERE idSeason = ?", (kodiid,))
|
kodicursor.execute("DELETE FROM seasons WHERE idSeason = ?", (kodiid,))
|
||||||
log.debug("Removed season: %s." % kodiid)
|
log.debug("Removed season: %s." % kodiid)
|
||||||
|
|
||||||
|
@ -1643,7 +1643,7 @@ class TVShows(Items):
|
||||||
|
|
||||||
kodicursor = self.kodicursor
|
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 episode WHERE idEpisode = ?", (kodiid,))
|
||||||
kodicursor.execute("DELETE FROM files WHERE idFile = ?", (fileid,))
|
kodicursor.execute("DELETE FROM files WHERE idFile = ?", (fileid,))
|
||||||
log.debug("Removed episode: %s." % kodiid)
|
log.debug("Removed episode: %s." % kodiid)
|
||||||
|
@ -1724,16 +1724,16 @@ class Music(Items):
|
||||||
|
|
||||||
##### The artist details #####
|
##### The artist details #####
|
||||||
lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
dateadded = API.getDateCreated()
|
dateadded = API.get_date_created()
|
||||||
checksum = API.getChecksum()
|
checksum = API.get_checksum()
|
||||||
|
|
||||||
name = item['Name']
|
name = item['Name']
|
||||||
musicBrainzId = API.getProvider('MusicBrainzArtist')
|
musicBrainzId = API.get_provider('MusicBrainzArtist')
|
||||||
genres = " / ".join(item.get('Genres'))
|
genres = " / ".join(item.get('Genres'))
|
||||||
bio = API.getOverview()
|
bio = API.get_overview()
|
||||||
|
|
||||||
# Associate artwork
|
# Associate artwork
|
||||||
artworks = artwork.getAllArtwork(item, parentInfo=True)
|
artworks = artwork.get_all_artwork(item, parent_info=True)
|
||||||
thumb = artworks['Primary']
|
thumb = artworks['Primary']
|
||||||
backdrops = artworks['Backdrop'] # List
|
backdrops = artworks['Backdrop'] # List
|
||||||
|
|
||||||
|
@ -1784,7 +1784,7 @@ class Music(Items):
|
||||||
|
|
||||||
|
|
||||||
# Update artwork
|
# Update artwork
|
||||||
artwork.addArtwork(artworks, artistid, "artist", kodicursor)
|
artwork.add_artwork(artworks, artistid, "artist", kodicursor)
|
||||||
|
|
||||||
def add_updateAlbum(self, item):
|
def add_updateAlbum(self, item):
|
||||||
# Process a single artist
|
# Process a single artist
|
||||||
|
@ -1805,16 +1805,16 @@ class Music(Items):
|
||||||
|
|
||||||
##### The album details #####
|
##### The album details #####
|
||||||
lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
lastScraped = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||||
dateadded = API.getDateCreated()
|
dateadded = API.get_date_created()
|
||||||
userdata = API.getUserData()
|
userdata = API.get_userdata()
|
||||||
checksum = API.getChecksum()
|
checksum = API.get_checksum()
|
||||||
|
|
||||||
name = item['Name']
|
name = item['Name']
|
||||||
musicBrainzId = API.getProvider('MusicBrainzAlbum')
|
musicBrainzId = API.get_provider('MusicBrainzAlbum')
|
||||||
year = item.get('ProductionYear')
|
year = item.get('ProductionYear')
|
||||||
genres = item.get('Genres')
|
genres = item.get('Genres')
|
||||||
genre = " / ".join(genres)
|
genre = " / ".join(genres)
|
||||||
bio = API.getOverview()
|
bio = API.get_overview()
|
||||||
rating = userdata['UserRating']
|
rating = userdata['UserRating']
|
||||||
artists = item['AlbumArtists']
|
artists = item['AlbumArtists']
|
||||||
if not artists:
|
if not artists:
|
||||||
|
@ -1825,7 +1825,7 @@ class Music(Items):
|
||||||
artistname = " / ".join(artistname)
|
artistname = " / ".join(artistname)
|
||||||
|
|
||||||
# Associate artwork
|
# Associate artwork
|
||||||
artworks = artwork.getAllArtwork(item, parentInfo=True)
|
artworks = artwork.get_all_artwork(item, parent_info=True)
|
||||||
thumb = artworks['Primary']
|
thumb = artworks['Primary']
|
||||||
if thumb:
|
if thumb:
|
||||||
thumb = "<thumb>%s</thumb>" % thumb
|
thumb = "<thumb>%s</thumb>" % thumb
|
||||||
|
@ -1952,7 +1952,7 @@ class Music(Items):
|
||||||
# Add genres
|
# Add genres
|
||||||
self.kodi_db.addMusicGenres(albumid, genres, "album")
|
self.kodi_db.addMusicGenres(albumid, genres, "album")
|
||||||
# Update artwork
|
# Update artwork
|
||||||
artwork.addArtwork(artworks, albumid, "album", kodicursor)
|
artwork.add_artwork(artworks, albumid, "album", kodicursor)
|
||||||
|
|
||||||
def add_updateSong(self, item):
|
def add_updateSong(self, item):
|
||||||
# Process single song
|
# Process single song
|
||||||
|
@ -1974,15 +1974,15 @@ class Music(Items):
|
||||||
log.debug("songid: %s not found." % itemid)
|
log.debug("songid: %s not found." % itemid)
|
||||||
|
|
||||||
##### The song details #####
|
##### The song details #####
|
||||||
checksum = API.getChecksum()
|
checksum = API.get_checksum()
|
||||||
dateadded = API.getDateCreated()
|
dateadded = API.get_date_created()
|
||||||
userdata = API.getUserData()
|
userdata = API.get_userdata()
|
||||||
playcount = userdata['PlayCount']
|
playcount = userdata['PlayCount']
|
||||||
dateplayed = userdata['LastPlayedDate']
|
dateplayed = userdata['LastPlayedDate']
|
||||||
|
|
||||||
# item details
|
# item details
|
||||||
title = item['Name']
|
title = item['Name']
|
||||||
musicBrainzId = API.getProvider('MusicBrainzTrackId')
|
musicBrainzId = API.get_provider('MusicBrainzTrackId')
|
||||||
genres = item.get('Genres')
|
genres = item.get('Genres')
|
||||||
genre = " / ".join(genres)
|
genre = " / ".join(genres)
|
||||||
artists = " / ".join(item['Artists'])
|
artists = " / ".join(item['Artists'])
|
||||||
|
@ -1993,7 +1993,7 @@ class Music(Items):
|
||||||
else:
|
else:
|
||||||
track = disc*2**16 + tracknumber
|
track = disc*2**16 + tracknumber
|
||||||
year = item.get('ProductionYear')
|
year = item.get('ProductionYear')
|
||||||
duration = API.getRuntime()
|
duration = API.get_runtime()
|
||||||
rating = userdata['UserRating']
|
rating = userdata['UserRating']
|
||||||
|
|
||||||
#if enabled, try to get the rating from file and/or emby
|
#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)
|
rating, comment, hasEmbeddedCover = musicutils.getAdditionalSongTags(itemid, rating, API, kodicursor, emby_db, self.enableimportsongrating, self.enableexportsongrating, self.enableupdatesongrating)
|
||||||
else:
|
else:
|
||||||
hasEmbeddedCover = False
|
hasEmbeddedCover = False
|
||||||
comment = API.getOverview()
|
comment = API.get_overview()
|
||||||
|
|
||||||
|
|
||||||
##### GET THE FILE AND PATH #####
|
##### GET THE FILE AND PATH #####
|
||||||
|
@ -2009,7 +2009,7 @@ class Music(Items):
|
||||||
path = "%s/emby/Audio/%s/" % (self.server, itemid)
|
path = "%s/emby/Audio/%s/" % (self.server, itemid)
|
||||||
filename = "stream.mp3"
|
filename = "stream.mp3"
|
||||||
else:
|
else:
|
||||||
playurl = API.getFilePath()
|
playurl = API.get_file_path()
|
||||||
|
|
||||||
if "\\" in playurl:
|
if "\\" in playurl:
|
||||||
# Local path
|
# Local path
|
||||||
|
@ -2063,7 +2063,7 @@ class Music(Items):
|
||||||
album_name = item.get('Album')
|
album_name = item.get('Album')
|
||||||
if album_name:
|
if album_name:
|
||||||
log.info("Creating virtual music album for song: %s." % itemid)
|
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")
|
emby_db.addReference("%salbum%s" % (itemid, albumid), albumid, "MusicAlbum_", "album")
|
||||||
else:
|
else:
|
||||||
# No album Id associated to the song.
|
# No album Id associated to the song.
|
||||||
|
@ -2257,14 +2257,14 @@ class Music(Items):
|
||||||
self.kodi_db.addMusicGenres(songid, genres, "song")
|
self.kodi_db.addMusicGenres(songid, genres, "song")
|
||||||
|
|
||||||
# Update artwork
|
# Update artwork
|
||||||
allart = artwork.getAllArtwork(item, parentInfo=True)
|
allart = artwork.get_all_artwork(item, parent_info=True)
|
||||||
if hasEmbeddedCover:
|
if hasEmbeddedCover:
|
||||||
allart["Primary"] = "image://music@" + artwork.single_urlencode( playurl )
|
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:
|
if item.get('AlbumId') is None:
|
||||||
# Update album artwork
|
# Update album artwork
|
||||||
artwork.addArtwork(allart, albumid, "album", kodicursor)
|
artwork.add_artwork(allart, albumid, "album", kodicursor)
|
||||||
|
|
||||||
def updateUserdata(self, item):
|
def updateUserdata(self, item):
|
||||||
# This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks
|
# This updates: Favorite, LastPlayedDate, Playcount, PlaybackPositionTicks
|
||||||
|
@ -2275,9 +2275,9 @@ class Music(Items):
|
||||||
|
|
||||||
# Get emby information
|
# Get emby information
|
||||||
itemid = item['Id']
|
itemid = item['Id']
|
||||||
checksum = API.getChecksum()
|
checksum = API.get_checksum()
|
||||||
userdata = API.getUserData()
|
userdata = API.get_userdata()
|
||||||
runtime = API.getRuntime()
|
runtime = API.get_runtime()
|
||||||
rating = userdata['UserRating']
|
rating = userdata['UserRating']
|
||||||
|
|
||||||
# Get Kodi information
|
# Get Kodi information
|
||||||
|
@ -2401,15 +2401,15 @@ class Music(Items):
|
||||||
|
|
||||||
kodicursor = self.kodicursor
|
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,))
|
self.kodicursor.execute("DELETE FROM song WHERE idSong = ?", (kodiId,))
|
||||||
|
|
||||||
def removeAlbum(self, 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,))
|
self.kodicursor.execute("DELETE FROM album WHERE idAlbum = ?", (kodiId,))
|
||||||
|
|
||||||
def removeArtist(self, 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,))
|
self.kodicursor.execute("DELETE FROM artist WHERE idArtist = ?", (kodiId,))
|
|
@ -420,7 +420,7 @@ class Kodidb_Functions():
|
||||||
if "writing" in arttype:
|
if "writing" in arttype:
|
||||||
arttype = "writer"
|
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):
|
def addGenres(self, kodiid, genres, mediatype):
|
||||||
|
|
||||||
|
|
|
@ -25,79 +25,72 @@ class KodiMonitor(xbmc.Monitor):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
self.doUtils = downloadutils.DownloadUtils()
|
self.download = downloadutils.DownloadUtils().downloadUrl
|
||||||
|
log.info("Kodi monitor started")
|
||||||
log.info("Kodi monitor started.")
|
|
||||||
|
|
||||||
|
|
||||||
def onScanStarted(self, library):
|
def onScanStarted(self, library):
|
||||||
log.debug("Kodi library scan %s running." % library)
|
|
||||||
|
log.debug("Kodi library scan %s running", library)
|
||||||
if library == "video":
|
if library == "video":
|
||||||
window('emby_kodiScan', value="true")
|
window('emby_kodiScan', value="true")
|
||||||
|
|
||||||
def onScanFinished(self, library):
|
def onScanFinished(self, library):
|
||||||
log.debug("Kodi library scan %s finished." % library)
|
|
||||||
|
log.debug("Kodi library scan %s finished", library)
|
||||||
if library == "video":
|
if library == "video":
|
||||||
window('emby_kodiScan', clear=True)
|
window('emby_kodiScan', clear=True)
|
||||||
|
|
||||||
def onSettingsChanged(self):
|
def onSettingsChanged(self):
|
||||||
# Monitor emby settings
|
# Monitor emby settings
|
||||||
# Review reset setting at a later time, need to be adjusted to account for initial setup
|
current_log_level = settings('logLevel')
|
||||||
# changes.
|
if window('emby_logLevel') != current_log_level:
|
||||||
'''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:
|
|
||||||
# The log level changed, set new prop
|
# The log level changed, set new prop
|
||||||
log.info("New log level: %s" % currentLog)
|
log.info("New log level: %s", current_log_level)
|
||||||
window('emby_logLevel', value=currentLog)
|
window('emby_logLevel', value=current_log_level)
|
||||||
|
|
||||||
def onNotification(self, sender, method, data):
|
def onNotification(self, sender, method, data):
|
||||||
|
|
||||||
doUtils = self.doUtils
|
if method not in ('Playlist.OnAdd', 'Player.OnStop', 'Player.OnClear'):
|
||||||
if method not in ("Playlist.OnAdd"):
|
log.info("Method: %s Data: %s", method, data)
|
||||||
log.info("Method: %s Data: %s" % (method, data))
|
|
||||||
|
|
||||||
if 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":
|
elif method == 'VideoLibrary.OnUpdate':
|
||||||
|
self._video_update(data)
|
||||||
|
|
||||||
|
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':
|
||||||
|
self._system_wake()
|
||||||
|
|
||||||
|
elif method == 'GUI.OnScreensaverDeactivated':
|
||||||
|
self._screensaver_deactivated()
|
||||||
|
|
||||||
|
def _on_play_(self, data):
|
||||||
# Set up report progress for emby playback
|
# Set up report progress for emby playback
|
||||||
item = data.get('item')
|
|
||||||
try:
|
try:
|
||||||
kodiid = item['id']
|
item = data['item']
|
||||||
|
kodi_id = item['id']
|
||||||
item_type = item['type']
|
item_type = item['type']
|
||||||
except (KeyError, TypeError):
|
except (KeyError, TypeError):
|
||||||
log.info("Item is invalid for playstate update.")
|
log.info("Item is invalid for playstate update")
|
||||||
else:
|
else:
|
||||||
if ((settings('useDirectPaths') == "1" and not item_type == "song") or
|
if ((settings('useDirectPaths') == "1" and not item_type == "song") or
|
||||||
(item_type == "song" and settings('enableMusic') == "true")):
|
(item_type == "song" and settings('enableMusic') == "true")):
|
||||||
# Set up properties for player
|
# Set up properties for player
|
||||||
embyconn = kodiSQL('emby')
|
item_id = self._get_item_id(kodi_id, item_type)
|
||||||
embycursor = embyconn.cursor()
|
if item_id:
|
||||||
emby_db = embydb.Embydb_Functions(embycursor)
|
url = "{server}/emby/Users/{UserId}/Items/%s?format=json" % item_id
|
||||||
emby_dbitem = emby_db.getItem_byKodiId(kodiid, item_type)
|
result = self.download(url)
|
||||||
try:
|
log.debug("Item: %s", result)
|
||||||
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)
|
|
||||||
|
|
||||||
playurl = None
|
playurl = None
|
||||||
count = 0
|
count = 0
|
||||||
|
@ -108,7 +101,7 @@ class KodiMonitor(xbmc.Monitor):
|
||||||
count += 1
|
count += 1
|
||||||
xbmc.sleep(200)
|
xbmc.sleep(200)
|
||||||
else:
|
else:
|
||||||
listItem = xbmcgui.ListItem()
|
listitem = xbmcgui.ListItem()
|
||||||
playback = pbutils.PlaybackUtils(result)
|
playback = pbutils.PlaybackUtils(result)
|
||||||
|
|
||||||
if item_type == "song" and settings('streamMusic') == "true":
|
if item_type == "song" and settings('streamMusic') == "true":
|
||||||
|
@ -116,101 +109,62 @@ class KodiMonitor(xbmc.Monitor):
|
||||||
else:
|
else:
|
||||||
window('emby_%s.playmethod' % playurl, value="DirectPlay")
|
window('emby_%s.playmethod' % playurl, value="DirectPlay")
|
||||||
# Set properties for player.py
|
# Set properties for player.py
|
||||||
playback.setProperties(playurl, listItem)
|
playback.setProperties(playurl, listitem)
|
||||||
finally:
|
|
||||||
embycursor.close()
|
|
||||||
|
|
||||||
|
def _video_update(self, data):
|
||||||
elif method == "VideoLibrary.OnUpdate":
|
|
||||||
# Manually marking as watched/unwatched
|
# Manually marking as watched/unwatched
|
||||||
playcount = data.get('playcount')
|
|
||||||
item = data.get('item')
|
|
||||||
try:
|
try:
|
||||||
kodiid = item['id']
|
item = data['item']
|
||||||
|
kodi_id = item['id']
|
||||||
item_type = item['type']
|
item_type = item['type']
|
||||||
except (KeyError, TypeError):
|
except (KeyError, TypeError):
|
||||||
log.info("Item is invalid for playstate update.")
|
log.info("Item is invalid for playstate update")
|
||||||
else:
|
else:
|
||||||
# Send notification to the server.
|
# Send notification to the server.
|
||||||
embyconn = kodiSQL('emby')
|
item_id = self._get_item_id(kodi_id, item_type)
|
||||||
embycursor = embyconn.cursor()
|
if item_id:
|
||||||
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.
|
# Stop from manually marking as watched unwatched, with actual playback.
|
||||||
if window('emby_skipWatched%s' % itemid) == "true":
|
if window('emby_skipWatched%s' % item_id) == "true":
|
||||||
# property is set in player.py
|
# property is set in player.py
|
||||||
window('emby_skipWatched%s' % itemid, clear=True)
|
window('emby_skipWatched%s' % item_id, clear=True)
|
||||||
else:
|
else:
|
||||||
# notify the server
|
# notify the server
|
||||||
url = "{server}/emby/Users/{UserId}/PlayedItems/%s?format=json" % itemid
|
url = "{server}/emby/Users/{UserId}/PlayedItems/%s?format=json" % item_id
|
||||||
if playcount != 0:
|
if data.get('playcount') != 0:
|
||||||
doUtils.downloadUrl(url, action_type="POST")
|
self.download(url, action_type="POST")
|
||||||
log.info("Mark as watched for itemid: %s" % itemid)
|
log.info("Mark as watched for itemid: %s", item_id)
|
||||||
else:
|
else:
|
||||||
doUtils.downloadUrl(url, action_type="DELETE")
|
self.download(url, action_type="DELETE")
|
||||||
log.info("Mark as unwatched for itemid: %s" % itemid)
|
log.info("Mark as unwatched for itemid: %s", item_id)
|
||||||
finally:
|
|
||||||
embycursor.close()
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
elif method == "VideoLibrary.OnRemove":
|
def _system_wake(cls):
|
||||||
# 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":
|
|
||||||
# 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
|
# Allow network to wake up
|
||||||
xbmc.sleep(10000)
|
xbmc.sleep(10000)
|
||||||
window('emby_online', value="false")
|
window('emby_online', value="false")
|
||||||
window('emby_onWake', value="true")
|
window('emby_onWake', value="true")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _screensaver_deactivated(cls):
|
||||||
|
|
||||||
elif method == "GUI.OnScreensaverDeactivated":
|
|
||||||
if settings('dbSyncScreensaver') == "true":
|
if settings('dbSyncScreensaver') == "true":
|
||||||
xbmc.sleep(5000);
|
xbmc.sleep(5000)
|
||||||
window('emby_onWake', value="true")
|
window('emby_onWake', value="true")
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_item_id(cls, kodi_id, item_type):
|
||||||
|
|
||||||
elif method == "Playlist.OnClear":
|
item_id = None
|
||||||
pass
|
|
||||||
|
conn = kodiSQL('emby')
|
||||||
|
cursor = conn.cursor()
|
||||||
|
emby_db = embydb.Embydb_Functions(cursor)
|
||||||
|
db_item = emby_db.getItem_byKodiId(kodi_id, item_type)
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
try:
|
||||||
|
item_id = db_item[0]
|
||||||
|
except TypeError:
|
||||||
|
log.info("Could not retrieve item Id")
|
||||||
|
|
||||||
|
return item_id
|
||||||
|
|
|
@ -1049,12 +1049,12 @@ class ManualSync(LibrarySync):
|
||||||
|
|
||||||
# Pull the list of movies and boxsets in Kodi
|
# Pull the list of movies and boxsets in Kodi
|
||||||
try:
|
try:
|
||||||
all_kodimovies = dict(emby_db.getChecksum('Movie'))
|
all_kodimovies = dict(emby_db.get_checksum('Movie'))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
all_kodimovies = {}
|
all_kodimovies = {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
all_kodisets = dict(emby_db.getChecksum('BoxSet'))
|
all_kodisets = dict(emby_db.get_checksum('BoxSet'))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
all_kodisets = {}
|
all_kodisets = {}
|
||||||
|
|
||||||
|
@ -1088,7 +1088,7 @@ class ManualSync(LibrarySync):
|
||||||
all_embymoviesIds.add(itemid)
|
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
|
# Only update if movie is not in Kodi or checksum is different
|
||||||
updatelist.append(itemid)
|
updatelist.append(itemid)
|
||||||
|
|
||||||
|
@ -1179,7 +1179,7 @@ class ManualSync(LibrarySync):
|
||||||
|
|
||||||
# Pull the list of musicvideos in Kodi
|
# Pull the list of musicvideos in Kodi
|
||||||
try:
|
try:
|
||||||
all_kodimvideos = dict(emby_db.getChecksum('MusicVideo'))
|
all_kodimvideos = dict(emby_db.get_checksum('MusicVideo'))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
all_kodimvideos = {}
|
all_kodimvideos = {}
|
||||||
|
|
||||||
|
@ -1211,7 +1211,7 @@ class ManualSync(LibrarySync):
|
||||||
all_embymvideosIds.add(itemid)
|
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
|
# Only update if musicvideo is not in Kodi or checksum is different
|
||||||
updatelist.append(itemid)
|
updatelist.append(itemid)
|
||||||
|
|
||||||
|
@ -1258,12 +1258,12 @@ class ManualSync(LibrarySync):
|
||||||
|
|
||||||
# Pull the list of tvshows and episodes in Kodi
|
# Pull the list of tvshows and episodes in Kodi
|
||||||
try:
|
try:
|
||||||
all_koditvshows = dict(emby_db.getChecksum('Series'))
|
all_koditvshows = dict(emby_db.get_checksum('Series'))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
all_koditvshows = {}
|
all_koditvshows = {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
all_kodiepisodes = dict(emby_db.getChecksum('Episode'))
|
all_kodiepisodes = dict(emby_db.get_checksum('Episode'))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
all_kodiepisodes = {}
|
all_kodiepisodes = {}
|
||||||
|
|
||||||
|
@ -1297,7 +1297,7 @@ class ManualSync(LibrarySync):
|
||||||
all_embytvshowsIds.add(itemid)
|
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
|
# Only update if movie is not in Kodi or checksum is different
|
||||||
updatelist.append(itemid)
|
updatelist.append(itemid)
|
||||||
|
|
||||||
|
@ -1341,7 +1341,7 @@ class ManualSync(LibrarySync):
|
||||||
itemid = embyepisode['Id']
|
itemid = embyepisode['Id']
|
||||||
all_embyepisodesIds.add(itemid)
|
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
|
# Only update if movie is not in Kodi or checksum is different
|
||||||
updatelist.append(itemid)
|
updatelist.append(itemid)
|
||||||
|
|
||||||
|
@ -1388,17 +1388,17 @@ class ManualSync(LibrarySync):
|
||||||
|
|
||||||
# Pull the list of artists, albums, songs
|
# Pull the list of artists, albums, songs
|
||||||
try:
|
try:
|
||||||
all_kodiartists = dict(emby_db.getChecksum('MusicArtist'))
|
all_kodiartists = dict(emby_db.get_checksum('MusicArtist'))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
all_kodiartists = {}
|
all_kodiartists = {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
all_kodialbums = dict(emby_db.getChecksum('MusicAlbum'))
|
all_kodialbums = dict(emby_db.get_checksum('MusicAlbum'))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
all_kodialbums = {}
|
all_kodialbums = {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
all_kodisongs = dict(emby_db.getChecksum('Audio'))
|
all_kodisongs = dict(emby_db.get_checksum('Audio'))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
all_kodisongs = {}
|
all_kodisongs = {}
|
||||||
|
|
||||||
|
@ -1429,17 +1429,17 @@ class ManualSync(LibrarySync):
|
||||||
itemid = embyitem['Id']
|
itemid = embyitem['Id']
|
||||||
if data_type == "artists":
|
if data_type == "artists":
|
||||||
all_embyartistsIds.add(itemid)
|
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
|
# Only update if artist is not in Kodi or checksum is different
|
||||||
updatelist.append(itemid)
|
updatelist.append(itemid)
|
||||||
elif data_type == "albums":
|
elif data_type == "albums":
|
||||||
all_embyalbumsIds.add(itemid)
|
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
|
# Only update if album is not in Kodi or checksum is different
|
||||||
updatelist.append(itemid)
|
updatelist.append(itemid)
|
||||||
else:
|
else:
|
||||||
all_embysongsIds.add(itemid)
|
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
|
# Only update if songs is not in Kodi or checksum is different
|
||||||
updatelist.append(itemid)
|
updatelist.append(itemid)
|
||||||
log.info("%s to update: %s" % (data_type, updatelist))
|
log.info("%s to update: %s" % (data_type, updatelist))
|
||||||
|
|
|
@ -74,7 +74,7 @@ def getAdditionalSongTags(embyid, emby_rating, API, kodicursor, emby_db, enablei
|
||||||
emby = embyserver.Read_EmbyServer()
|
emby = embyserver.Read_EmbyServer()
|
||||||
|
|
||||||
previous_values = None
|
previous_values = None
|
||||||
filename = API.getFilePath()
|
filename = API.get_file_path()
|
||||||
rating = 0
|
rating = 0
|
||||||
emby_rating = int(round(emby_rating, 0))
|
emby_rating = int(round(emby_rating, 0))
|
||||||
|
|
||||||
|
|
|
@ -82,8 +82,8 @@ class PlaybackUtils():
|
||||||
|
|
||||||
############### RESUME POINT ################
|
############### RESUME POINT ################
|
||||||
|
|
||||||
userdata = self.API.getUserData()
|
userdata = self.API.get_userdata()
|
||||||
seektime = self.API.adjustResume(userdata['Resume'])
|
seektime = self.API.adjust_resume(userdata['Resume'])
|
||||||
|
|
||||||
# We need to ensure we add the intro and additional parts only once.
|
# We need to ensure we add the intro and additional parts only once.
|
||||||
# Otherwise we get a loop.
|
# Otherwise we get a loop.
|
||||||
|
@ -309,7 +309,7 @@ class PlaybackUtils():
|
||||||
|
|
||||||
def setArtwork(self, listItem):
|
def setArtwork(self, listItem):
|
||||||
# Set up item and item info
|
# 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
|
# Set artwork for listitem
|
||||||
arttypes = {
|
arttypes = {
|
||||||
|
|
||||||
|
@ -346,20 +346,20 @@ class PlaybackUtils():
|
||||||
|
|
||||||
def setListItem(self, listItem):
|
def setListItem(self, listItem):
|
||||||
|
|
||||||
people = self.API.getPeople()
|
people = self.API.get_people()
|
||||||
studios = self.API.getStudios()
|
studios = self.API.get_studios()
|
||||||
|
|
||||||
metadata = {
|
metadata = {
|
||||||
|
|
||||||
'title': self.item.get('Name', "Missing name"),
|
'title': self.item.get('Name', "Missing name"),
|
||||||
'year': self.item.get('ProductionYear'),
|
'year': self.item.get('ProductionYear'),
|
||||||
'plot': self.API.getOverview(),
|
'plot': self.API.get_overview(),
|
||||||
'director': people.get('Director'),
|
'director': people.get('Director'),
|
||||||
'writer': people.get('Writer'),
|
'writer': people.get('Writer'),
|
||||||
'mpaa': self.API.getMpaa(),
|
'mpaa': self.API.get_mpaa(),
|
||||||
'genre': " / ".join(self.item['Genres']),
|
'genre': " / ".join(self.item['Genres']),
|
||||||
'studio': " / ".join(studios),
|
'studio': " / ".join(studios),
|
||||||
'aired': self.API.getPremiereDate(),
|
'aired': self.API.get_premiere_date(),
|
||||||
'rating': self.item.get('CommunityRating'),
|
'rating': self.item.get('CommunityRating'),
|
||||||
'votes': self.item.get('VoteCount')
|
'votes': self.item.get('VoteCount')
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,7 +147,7 @@ class UserClient(threading.Thread):
|
||||||
settings('username', value=self._user['Name'])
|
settings('username', value=self._user['Name'])
|
||||||
if "PrimaryImageTag" in self._user:
|
if "PrimaryImageTag" in self._user:
|
||||||
window('EmbyUserImage',
|
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")
|
self._server = self.download("{server}/emby/System/Configuration?format=json")
|
||||||
settings('markPlayed', value=str(self._server['MaxResumePct']))
|
settings('markPlayed', value=str(self._server['MaxResumePct']))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue