Skip to content

Commit

Permalink
✨ Allow skinvariables templates to addnfo with operations
Browse files Browse the repository at this point in the history
  • Loading branch information
jurialmunkey committed Nov 12, 2023
1 parent adedb70 commit c8b3cac
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 131 deletions.
139 changes: 9 additions & 130 deletions resources/lib/method.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class FileUtils(jurialmunkey.futils.FileUtils):
boolean = jurialmunkey.parser.boolean


def _set_animation(animations):
def set_animation_list(animations):
import xbmcgui
win_id = xbmcgui.getCurrentWindowId()
window = xbmcgui.Window(win_id)
Expand All @@ -24,14 +24,14 @@ def _set_animation(animations):


def set_animation(set_animation, **kwargs):
_set_animation([
set_animation_list([
(control_id, event, effect,)
for i in set_animation.split('||')
for control_id, event, effect in i.split('|')
])


def _run_executebuiltin(builtins):
def run_executebuiltin_list(builtins):
import xbmc
for builtin in builtins:
if builtin.startswith('sleep='):
Expand All @@ -44,7 +44,7 @@ def _run_executebuiltin(builtins):
if builtin.startswith('animation='):
animation = builtin[10:]
control_id, event, effect = animation.split('|')
_set_animation([(control_id, event, effect, )])
set_animation_list([(control_id, event, effect, )])
continue
xbmc.executebuiltin(builtin)

Expand All @@ -53,137 +53,16 @@ def run_executebuiltin(run_executebuiltin=None, use_rules=False, **kwargs):
if not run_executebuiltin:
return
if not boolean(use_rules):
return _run_executebuiltin(run_executebuiltin.split('||'))
return run_executebuiltin_list(run_executebuiltin.split('||'))

import re
import xbmc
from json import loads
from jurialmunkey.futils import load_filecontent
from resources.lib.operations import RuleOperations

meta = loads(str(load_filecontent(run_executebuiltin)))

def _check_rules(rules):
result = True
for rule in rules:
# Rules can have sublists of rules
if isinstance(rule, list):
result = _check_rules(rule)
if not result:
continue
return True
rule = rule.format(**kwargs)
if not xbmc.getCondVisibility(rule):
return False
return result

def _get_actions_list(rule_actions):
actions_list = []

if not isinstance(rule_actions, list):
rule_actions = [rule_actions]

for action in rule_actions:

# Parts are prefixed with percent % so needs to be replaced
if isinstance(action, str) and action.startswith('%'):
action = action.format(**kwargs)
action = meta['parts'][action[1:]]

# Standard actions are strings - add formatted action to list and continue
if isinstance(action, str):
actions_list.append(action.format(**kwargs))
continue

# Sublists of actions are lists - recursively add sublists and continue
if isinstance(action, list):
actions_list += _get_actions_list(action)
continue

# Rules are dictionaries - successful rules add their actions and stop iterating (like a skin variable)
if _check_rules(action['rules']):
actions_list += _get_actions_list(action['value'])
break

return actions_list

def _set_infolabels(d):
for k, v in d.items():
k = k.format(**kwargs)
v = v.format(**kwargs)
kwargs[k] = xbmc.getInfoLabel(v)

def _set_regex(d):
for k, v in d.items():
k = k.format(**kwargs)
kwargs[k] = re.sub(v['regex'].format(**kwargs), v['value'].format(**kwargs), v['input'].format(**kwargs))

def _set_values(d):
for k, v in d.items():
k = k.format(**kwargs)
kwargs[k] = _get_actions_list(v)[0]

def _set_sums(d):
for k, v in d.items():
k = k.format(**kwargs)
kwargs[k] = sum([int(i.format(**kwargs)) for i in v])

def _set_decode(d):
from urllib.parse import unquote_plus
for k, v in d.items():
k = k.format(**kwargs)
v = v.format(**kwargs)
kwargs[k] = unquote_plus(v)

def _set_encode(d):
from urllib.parse import quote_plus
for k, v in d.items():
k = k.format(**kwargs)
v = v.format(**kwargs)
kwargs[k] = quote_plus(v)

def _set_escape(d):
from xml.sax.saxutils import escape
for k, v in d.items():
k = k.format(**kwargs)
v = v.format(**kwargs)
kwargs[k] = escape(v)

def _set_lower(d):
for k, v in d.items():
k = k.format(**kwargs)
kwargs[k] = v.format(**kwargs).lower()

def _set_upper(d):
for k, v in d.items():
k = k.format(**kwargs)
kwargs[k] = v.format(**kwargs).upper()

def _set_capitalize(d):
for k, v in d.items():
k = k.format(**kwargs)
kwargs[k] = v.format(**kwargs).capitalize()

routes = {
'infolabels': _set_infolabels,
'regex': _set_regex,
'values': _set_values,
'sums': _set_sums,
'decode': _set_decode,
'encode': _set_encode,
'escape': _set_escape,
'lower': _set_lower,
'upper': _set_upper,
'capitalize': _set_capitalize,
}

operations = [{i: meta[i]} for i in routes if i in meta] + meta.get('operations', [])

for i in operations:
for k, v in i.items():
routes[k](v)

actions_list = _get_actions_list(meta['actions'])
return _run_executebuiltin(actions_list)
rule_operations = RuleOperations(meta, **kwargs)
actions_list = rule_operations.get_actions_list(rule_operations.meta['actions'])
return run_executebuiltin_list(actions_list)


def get_paramstring_tuplepairs(paramstring):
Expand Down
138 changes: 138 additions & 0 deletions resources/lib/operations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import re
import xbmc


class RuleOperations():
def __init__(self, meta, **params):
self.meta = meta
self.params = params
self.run_operations()

def run_operations(self):
for i in self.operations:
for k, v in i.items():
self.routes[k](v)

@property
def operations(self):
return [{i: self.meta[i]} for i in self.routes if i in self.meta] + self.meta.get('operations', [])

@property
def routes(self):
try:
return self._routes
except AttributeError:
self._routes = {
'infolabels': self.set_infolabels,
'regex': self.set_regex,
'values': self.set_values,
'sums': self.set_sums,
'decode': self.set_decode,
'encode': self.set_encode,
'escape': self.set_escape,
'lower': self.set_lower,
'upper': self.set_upper,
'capitalize': self.set_capitalize,
}
return self._routes

def set_infolabels(self, d):
for k, v in d.items():
k = k.format(**self.params)
v = v.format(**self.params)
self.params[k] = xbmc.getInfoLabel(v)

def set_regex(self, d):
for k, v in d.items():
k = k.format(**self.params)
self.params[k] = re.sub(v['regex'].format(**self.params), v['value'].format(**self.params), v['input'].format(**self.params))

def set_values(self, d):
for k, v in d.items():
k = k.format(**self.params)
self.params[k] = self.get_actions_list(v)[0]

def set_sums(self, d):
for k, v in d.items():
k = k.format(**self.params)
self.params[k] = sum([int(i.format(**self.params)) for i in v])

def set_decode(self, d):
from urllib.parse import unquote_plus
for k, v in d.items():
k = k.format(**self.params)
v = v.format(**self.params)
self.params[k] = unquote_plus(v)

def set_encode(self, d):
from urllib.parse import quote_plus
for k, v in d.items():
k = k.format(**self.params)
v = v.format(**self.params)
self.params[k] = quote_plus(v)

def set_escape(self, d):
from xml.sax.saxutils import escape
for k, v in d.items():
k = k.format(**self.params)
v = v.format(**self.params)
self.params[k] = escape(v)

def set_lower(self, d):
for k, v in d.items():
k = k.format(**self.params)
self.params[k] = v.format(**self.params).lower()

def set_upper(self, d):
for k, v in d.items():
k = k.format(**self.params)
self.params[k] = v.format(**self.params).upper()

def set_capitalize(self, d):
for k, v in d.items():
k = k.format(**self.params)
self.params[k] = v.format(**self.params).capitalize()

def check_rules(self, rules):
result = True
for rule in rules:
# Rules can have sublists of rules
if isinstance(rule, list):
result = self.check_rules(rule)
if not result:
continue
return True
rule = rule.format(**self.params)
if not xbmc.getCondVisibility(rule):
return False
return result

def get_actions_list(self, rule_actions):
actions_list = []

if not isinstance(rule_actions, list):
rule_actions = [rule_actions]

for action in rule_actions:

# Parts are prefixed with percent % so needs to be replaced
if isinstance(action, str) and action.startswith('%'):
action = action.format(**self.params)
action = self.meta['parts'][action[1:]]

# Standard actions are strings - add formatted action to list and continue
if isinstance(action, str):
actions_list.append(action.format(**self.params))
continue

# Sublists of actions are lists - recursively add sublists and continue
if isinstance(action, list):
actions_list += self.get_actions_list(action)
continue

# Rules are dictionaries - successful rules add their actions and stop iterating (like a skin variable)
if self.check_rules(action['rules']):
actions_list += self.get_actions_list(action['value'])
break

return actions_list
6 changes: 5 additions & 1 deletion resources/lib/skinshortcuts_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ def update_xml(self, force=False, no_reload=False, genxml='', **kwargs):
self.meta['genxml'] += [{k: v for j in i.split('|') for k, v in (j.split('='), )} for i in genxml.split('||')] if genxml else []
self.meta['getnfo'] = {k: xbmc.getInfoLabel(v) for k, v in self.meta['getnfo'].items()} if 'getnfo' in self.meta else {}
self.meta['getnfo'].update(kwargs)
self.meta['getnfo'].update({f'{k}_escaped': escape(v) for k, v in self.meta['getnfo'].items() if not k.endswith('_escaped')})
self.meta['getnfo'].update({f'{k}_escaped': escape(v) for k, v in self.meta['getnfo'].items() if v and k and not k.endswith('_escaped')})

if 'addnfo' in self.meta:
from resources.lib.operations import RuleOperations
self.meta['getnfo'].update(RuleOperations(self.meta['addnfo'], **self.meta['getnfo']).params)

content = self.create_xml(
self.meta['genxml'],
Expand Down

0 comments on commit c8b3cac

Please sign in to comment.