Skip to content

Commit

Permalink
✨ Allow an {x} value in sourceimage
Browse files Browse the repository at this point in the history
  • Loading branch information
jurialmunkey committed Dec 21, 2024
1 parent 2d1f0d5 commit dea75e9
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 49 deletions.
7 changes: 5 additions & 2 deletions resources/tmdbhelper/lib/monitor/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@

SETMAIN = {
'label', 'tmdb_id', 'imdb_id', 'folderpath', 'filenameandpath'}
SETMAIN_ALTERED = {
'cropimage', 'cropimage.original', 'blurimage', 'blurimage.original',
'desaturateimage', 'desaturateimage.original', 'colorsimage', 'colorsimage.original'}
SETMAIN_ARTWORK = {
'cropimage', 'cropimage.original', 'blurimage', 'blurimage.original', 'desaturateimage', 'desaturateimage.original', 'colorsimage', 'colorsimage.original',
'icon', 'poster', 'thumb', 'fanart', 'discart', 'clearart', 'clearlogo', 'landscape', 'banner', 'keyart',
'season.poster', 'season.thumb', 'season.fanart', 'season.discart', 'season.clearart', 'season.clearlogo', 'season.landscape', 'season.banner', 'season.keyart',
'tvshow.poster', 'tvshow.thumb', 'tvshow.fanart', 'tvshow.discart', 'tvshow.clearart', 'tvshow.clearlogo', 'tvshow.landscape', 'tvshow.banner', 'tvshow.keyart'}
Expand Down Expand Up @@ -283,7 +285,8 @@ def set_indexed_properties(self, dictionary):
k for k in list(dictionary)
if k not in self.properties
and k not in SETPROP_RATINGS
and k not in SETMAIN_ARTWORK)
and k not in SETMAIN_ARTWORK
and k not in SETMAIN_ALTERED)

for k in keys:
if k not in dictionary:
Expand Down
136 changes: 97 additions & 39 deletions resources/tmdbhelper/lib/monitor/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import xbmcvfs
import colorsys
import hashlib
import random
from xbmc import getCacheThumbName, skinHasImage, Monitor, sleep
from tmdbhelper.lib.addon.plugin import get_infolabel, get_setting, get_condvisibility, ADDONDATA
from tmdbhelper.lib.monitor.propertysetter import PropertySetter
Expand Down Expand Up @@ -350,6 +351,93 @@ def colors(self, source):
return ''


class ImageArtworkGetter():
def __init__(self, parent, source, prebuilt_artwork=None):
self._parent = parent
self._source = source
self.prebuilt_artwork = prebuilt_artwork

@property
def infolabels(self):
try:
return self._infolabels
except AttributeError:
self._infolabels = self.get_infolabels()
return self._infolabels

def get_infolabels(self):
if not self._source:
return ARTWORK_LOOKUP_TABLE.get('thumb')
return ARTWORK_LOOKUP_TABLE.get(self._source, self._source.split("|"))

@property
def built_artwork(self):
try:
return self._built_artwork
except AttributeError:
self._built_artwork = self.get_built_artwork()
return self._built_artwork

def get_built_artwork(self):
return self.prebuilt_artwork or self._parent.get_builtartwork()

@property
def artwork(self):
try:
return self._artwork
except AttributeError:
self._artwork = self.get_artwork()
return self._artwork

def get_artwork(self):
return next((j for j in (self.get_artwork_item(i) for i in self.infolabels) if j), None)

@property
def artwork_fallback(self):
try:
return self._artwork_fallback
except AttributeError:
self._artwork_fallback = self.get_artwork_fallback()
return self._artwork_fallback

def get_artwork_fallback(self):
return next((j for j in (self.get_artwork_item(i, prebuilt=True) for i in self.infolabels) if j), None)

def get_artwork_item(self, item, prebuilt=False):

def _get_artwork_item(i, x=''):
if not prebuilt:
return self._parent.get_infolabel(i.format(x=x))
if not i.startswith('art('):
return
return self.built_artwork.get(i.format(x=x)[4:-1])

# Check if we're getting a random x position item e.g. "Art(fanart{x})"
if '{x}' not in item:
return _get_artwork_item(item)

# If we cant get the base item e.g. "Art(fanart)" then unlikely we have extra art so exit now
artwork0 = _get_artwork_item(item)
if not artwork0:
return

# If we can't get the first extra item e.g. "Art(fanart1)" then unlikely we'd have "Art(fanart2)" etc. so just return "Art(fanart)"
artwork1 = _get_artwork_item(item, x=1)
if not artwork1:
return artwork0

# Build a list of available artworks that the item has
artworks = [artwork0, artwork1]
for x in range(2, 9):
artwork = _get_artwork_item(item, x=x)
if not artwork:
break
artworks.append(artwork)

# Then choose an artwork from the available artworks list at random
return random.choice(artworks)


class ImageManipulations(PropertySetter):
def get_infolabel(self, info):
return get_infolabel(f'ListItem.{info}')
Expand All @@ -361,48 +449,16 @@ def get_artwork(self, source='', build_fallback=False, built_artwork=None):
source = source or ''
source = source.lower()

def _get_artwork_infolabel(_infolabels):
for i in _infolabels:
artwork = self.get_infolabel(i)
if not artwork:
continue
return artwork

def _get_artwork_fallback(_infolabels, _built_artwork):
for i in _infolabels:
if not i.startswith('art('):
continue
artwork = _built_artwork.get(i[4:-1])
if not artwork:
continue
return artwork

def _get_artwork(_source):
if _source:
_infolabels = ARTWORK_LOOKUP_TABLE.get(_source, _source.split("|"))
else:
_infolabels = ARTWORK_LOOKUP_TABLE.get('thumb')

artwork = _get_artwork_infolabel(_infolabels)

if artwork or not build_fallback:
return artwork

nonlocal built_artwork

built_artwork = built_artwork or self.get_builtartwork()
if not built_artwork:
return

return _get_artwork_fallback(_infolabels, built_artwork)

for _source in source.split("||"):
artwork = _get_artwork(_source)
if not artwork:
img_get = ImageArtworkGetter(self, _source, prebuilt_artwork=built_artwork)
if img_get.artwork:
return img_get.artwork
if not build_fallback or not img_get.built_artwork:
continue
return artwork
if img_get.artwork_fallback:
return img_get.artwork_fallback

def get_image_manipulations(self, use_winprops=False, built_artwork=None):
def get_image_manipulations(self, use_winprops=False, built_artwork=None, allow_list=('crop', 'blur', 'desaturate', 'colors', )):
images = {}

_manipulations = (
Expand Down Expand Up @@ -435,6 +491,8 @@ def get_image_manipulations(self, use_winprops=False, built_artwork=None):
or self.get_property('Colors.Fallback')},)

for i in _manipulations:
if i['method'] not in allow_list:
continue
if not i['active']():
continue
imgfunc = ImageFunctions(method=i['method'], is_thread=False, artwork=i['images']())
Expand Down
23 changes: 21 additions & 2 deletions resources/tmdbhelper/lib/monitor/imgmon.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,45 @@ class ImagesMonitor(Thread, ListItemInfoGetter, ImageManipulations, Poller):
"!Skin.HasSetting(TMDbHelper.EnableDesaturate) + "
"!Skin.HasSetting(TMDbHelper.EnableColors)")

_allow_list = ('crop', 'blur', 'desaturate', 'colors', )
idle_cycles = 10 / POLL_MIN_INCREMENT # Reupdate idle item every ten seconds for extrafanart TODO: Allow skin to set value?

def __init__(self, parent):
Thread.__init__(self)
self._cur_item = 0
self._pre_item = 1
self._cur_window = 0
self._pre_window = 1
self._idle_cycle = 0
self.exit = False
self.update_monitor = parent.update_monitor
self.crop_image_cur = None
self.blur_image_cur = None
self.remote_artwork = {}
self.added_artworks = {}
self._allow_on_scroll = True # Allow updating while scrolling
self._parent = parent

@kodi_try_except('lib.monitor.imgmon.on_listitem')
def on_listitem(self):
with self._parent.mutex_lock:
self.setup_current_container()
if self.is_same_item(update=True):
if self.is_same_item(update=True) and self._idle_cycle < self.idle_cycles:
self._idle_cycle += 1
return
self.get_image_manipulations(use_winprops=True)
self._idle_cycle = 0
self.update_artwork()

def get_allow_list(self, check_set=False):
if not check_set:
return self._allow_list
return [k for k in self._allow_list if not self.get_property(f'ListItem.{k}Image')]

def update_artwork(self, check_set=False):
self.added_artworks[self._pre_item] = self.get_image_manipulations(
use_winprops=True,
built_artwork=self.remote_artwork.get(self._pre_item),
allow_list=self.get_allow_list(check_set=check_set))

def _on_listitem(self):
self.on_listitem()
Expand Down
11 changes: 6 additions & 5 deletions resources/tmdbhelper/lib/monitor/listitemtools.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from tmdbhelper.lib.addon.plugin import get_infolabel, get_condvisibility, get_localized, get_setting, get_skindir
from tmdbhelper.lib.addon.logger import kodi_try_except
from jurialmunkey.window import get_property, get_current_window
from tmdbhelper.lib.monitor.common import CommonMonitorFunctions, SETMAIN_ARTWORK, SETPROP_RATINGS
from tmdbhelper.lib.monitor.common import CommonMonitorFunctions, SETMAIN_ARTWORK, SETPROP_RATINGS, SETMAIN_ALTERED
from tmdbhelper.lib.monitor.itemdetails import ListItemDetails
from tmdbhelper.lib.monitor.readahead import ListItemReadAhead, READAHEAD_CHANGED
from tmdbhelper.lib.monitor.baseitem import BaseItemSkinDefaults
Expand Down Expand Up @@ -264,13 +264,14 @@ def on_finalise_winproperties(self, process_artwork=True, process_ratings=True):
# Proces artwork in a thread
def _process_artwork():
_artwork = _item.get_builtartwork()
_artwork.update(_item.get_image_manipulations(built_artwork=_artwork, use_winprops=False))
_artwork_properties = set()

if _pre_item != self.cur_item:
return

with self._parent.mutex_lock:
if _pre_item != self.cur_item:
return
self._parent.images_monitor._pre_item = _pre_item
self._parent.images_monitor.remote_artwork[_pre_item] = _artwork.copy()
self._parent.images_monitor.update_artwork(check_set=True)
self.set_iter_properties(_artwork, SETMAIN_ARTWORK, property_object=_artwork_properties)
self.clear_property_list(SETMAIN_ARTWORK.difference(_artwork_properties))

Expand Down
3 changes: 2 additions & 1 deletion resources/tmdbhelper/lib/monitor/player.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from xbmc import Player
from jurialmunkey.parser import boolean
from jurialmunkey.window import get_property
from tmdbhelper.lib.monitor.common import CommonMonitorFunctions, SETPROP_RATINGS, SETMAIN_ARTWORK
from tmdbhelper.lib.monitor.common import CommonMonitorFunctions, SETPROP_RATINGS, SETMAIN_ARTWORK, SETMAIN_ALTERED
from tmdbhelper.lib.addon.plugin import get_condvisibility, get_infolabel


Expand Down Expand Up @@ -138,6 +138,7 @@ def get_playingitem(self):
self.properties.add('CropImage')
self.properties.add('CropImage.Original')
self.set_iter_properties(self.details.get('art', {}), SETMAIN_ARTWORK)
self.set_iter_properties(self.details.get('art', {}), SETMAIN_ALTERED)

self.set_properties(self.details)

Expand Down

0 comments on commit dea75e9

Please sign in to comment.