mirror of
https://github.com/Team-Resurgent/XBMC4Xbox.git
synced 2026-08-15 11:18:13 -07:00
156 lines
6.4 KiB
Python
156 lines
6.4 KiB
Python
##################################################
|
|||
|
|
# SPYCE - Python-based HTML Scripting
|
||
|
|
# Copyright (c) 2002 Rimon Barr.
|
||
|
|
#
|
||
|
|
# Refer to spyce.py
|
||
|
|
# CVS: $Id: transform.py 31144 2012-07-15 15:38:56Z buzz $
|
||
|
|
##################################################
|
||
|
|
|
||
|
|
from spyceModule import spyceModule
|
||
|
|
import types, re, string
|
||
|
|
|
||
|
|
__doc__ = '''Transform module intercepts different kinds of Spyce ouput, and
|
||
|
|
can install functions to perform processing. It also includes some standard
|
||
|
|
Spyce transformation functions.'''
|
||
|
|
|
||
|
|
OUTPUT_POSITON = 20
|
||
|
|
|
||
|
|
class transform(spyceModule):
|
||
|
|
def start(self):
|
||
|
|
self.ident = lambda x, **kwargs: x
|
||
|
|
self._filter = FilterFn(self.ident, self.ident, self.ident)
|
||
|
|
# install filter functions into response module
|
||
|
|
self._prevfilter = self._api.getModule('response').addFilter(OUTPUT_POSITON, self._filter)
|
||
|
|
def finish(self, theError=None):
|
||
|
|
self._prevfilter = self._api.getModule('response').addFilter(OUTPUT_POSITON, self._prevfilter)
|
||
|
|
# set filters
|
||
|
|
def dynamic(self, fn=None):
|
||
|
|
if not fn: fn = self.ident
|
||
|
|
self._filter.dynamicFilter = self.create(fn)
|
||
|
|
def static(self, fn=None):
|
||
|
|
if not fn: fn = self.ident
|
||
|
|
self._filter.staticFilter = self.create(fn)
|
||
|
|
def expr(self, fn=None):
|
||
|
|
if not fn: fn = self.ident
|
||
|
|
self._filter.exprFilter = self.create(fn)
|
||
|
|
# create filter
|
||
|
|
def create(self, fn):
|
||
|
|
'''Create filter function.'''
|
||
|
|
if fn==None or fn==() or fn==[]:
|
||
|
|
# identity
|
||
|
|
return self.ident
|
||
|
|
elif type(fn) == types.FunctionType:
|
||
|
|
# function type
|
||
|
|
return fn
|
||
|
|
elif type(fn) == type(''):
|
||
|
|
# string
|
||
|
|
file_name = string.split(fn, ':')
|
||
|
|
if len(file_name)==1: file, name = None, file_name[0]
|
||
|
|
else: file, name = file_name[:2]
|
||
|
|
if file: fn = loadModule(name, file, self._api.getFilename())
|
||
|
|
else: fn = eval(name)
|
||
|
|
return fn
|
||
|
|
elif type(fn) == type(()) or type(fn) == type([]):
|
||
|
|
# tuple or array
|
||
|
|
fn0 = self.create(fn[0])
|
||
|
|
fn1 = self.create(fn[1:])
|
||
|
|
def filterfn(x, _fn0=fn0, _fn1=fn1, **kwargs):
|
||
|
|
x = apply(_fn0, (x,), kwargs)
|
||
|
|
return apply(_fn1, (x,), kwargs)
|
||
|
|
return filterfn
|
||
|
|
# commonly used transformations
|
||
|
|
def html_encode(self, s, also='', **kwargs):
|
||
|
|
'''Return HTML-encoded string.'''
|
||
|
|
return html_encode(s, also)
|
||
|
|
def url_encode(self, s, **kwargs):
|
||
|
|
'''Return url-encoded string.'''
|
||
|
|
return url_encode(s)
|
||
|
|
def __repr__(self):
|
||
|
|
return 'static: %s, expr: %s, dynamic: %s' % (
|
||
|
|
str(self._filter.staticFilter!=self.ident),
|
||
|
|
str(self._filter.exprFilter!=self.ident),
|
||
|
|
str(self._filter.dynamicFilter!=self.ident),
|
||
|
|
)
|
||
|
|
|
||
|
|
class FilterFn(Filter):
|
||
|
|
def __init__(self, dynamicFilter=None, staticFilter=None, exprFilter=None):
|
||
|
|
ident = lambda x: x
|
||
|
|
if not dynamicFilter: dynamicFilter = ident
|
||
|
|
if not staticFilter: staticFilter = ident
|
||
|
|
if not exprFilter: exprFilter = ident
|
||
|
|
self.dynamicFilter = dynamicFilter
|
||
|
|
self.staticFilter = staticFilter
|
||
|
|
self.exprFilter = exprFilter
|
||
|
|
def dynamicImpl(self, s, *args, **kwargs):
|
||
|
|
return apply(self.dynamicFilter, (s,)+args, kwargs)
|
||
|
|
def staticImpl(self, s, *args, **kwargs):
|
||
|
|
return apply(self.staticFilter, (s,)+args, kwargs)
|
||
|
|
def exprImpl(self, s, *args, **kwargs):
|
||
|
|
return apply(self.exprFilter, (s,)+args, kwargs)
|
||
|
|
def flushImpl(self):
|
||
|
|
pass
|
||
|
|
def clearImpl(self):
|
||
|
|
pass
|
||
|
|
|
||
|
|
# standard transformation functions
|
||
|
|
def ignore_none(o, **kwargs):
|
||
|
|
'''Does not print None.'''
|
||
|
|
if o==None: return ''
|
||
|
|
else: return o
|
||
|
|
|
||
|
|
def silence(o, **kwargs):
|
||
|
|
'''Gobbles anything.'''
|
||
|
|
return ''
|
||
|
|
|
||
|
|
def truncate(o, maxlen=None, **kwargs):
|
||
|
|
'''Limits output to a maximum string length.'''
|
||
|
|
if maxlen!=None: return str(o)[:maxlen]
|
||
|
|
else: return o
|
||
|
|
|
||
|
|
_html_enc = {
|
||
|
|
chr(34): '"', chr(38): '&', chr(60): '<', chr(62): '>',
|
||
|
|
chr(160): ' ', chr(161): '¡', chr(162): '¢', chr(163): '£',
|
||
|
|
chr(164): '¤', chr(165): '¥', chr(166): '¦', chr(167): '§',
|
||
|
|
chr(168): '¨', chr(169): '©', chr(170): 'ª', chr(171): '«',
|
||
|
|
chr(172): '¬', chr(173): '­', chr(174): '®', chr(175): '¯',
|
||
|
|
chr(176): '°', chr(177): '±', chr(178): '²', chr(179): '³',
|
||
|
|
chr(180): '´', chr(181): 'µ', chr(182): '¶', chr(183): '·',
|
||
|
|
chr(184): '¸', chr(185): '¹', chr(186): 'º', chr(187): '»',
|
||
|
|
chr(188): '¼', chr(189): '½', chr(190): '¾', chr(191): '¿',
|
||
|
|
chr(192): 'À', chr(193): 'Á', chr(194): 'Â', chr(195): 'Ã',
|
||
|
|
chr(196): 'Ä', chr(197): 'Å', chr(198): 'Æ', chr(199): 'Ç',
|
||
|
|
chr(200): 'È', chr(201): 'É', chr(202): 'Ê', chr(203): 'Ë',
|
||
|
|
chr(204): 'Ì', chr(205): 'Í', chr(206): 'Î', chr(207): 'Ï',
|
||
|
|
chr(208): 'Ð', chr(209): 'Ñ', chr(210): 'Ò', chr(211): 'Ó',
|
||
|
|
chr(212): 'Ô', chr(213): 'Õ', chr(214): 'Ö', chr(215): '×',
|
||
|
|
chr(216): 'Ø', chr(217): 'Ù', chr(218): 'Ú', chr(219): 'Û',
|
||
|
|
chr(220): 'Ü', chr(221): 'Ý', chr(222): 'Þ', chr(223): 'ß',
|
||
|
|
chr(224): 'à', chr(225): 'á', chr(226): 'â', chr(227): 'ã',
|
||
|
|
chr(228): 'ä', chr(229): 'å', chr(230): 'æ', chr(231): 'ç',
|
||
|
|
chr(232): 'è', chr(233): 'é', chr(234): 'ê', chr(235): 'ë',
|
||
|
|
chr(236): 'ì', chr(237): 'í', chr(238): 'î', chr(239): 'ï',
|
||
|
|
chr(240): 'ð', chr(241): 'ñ', chr(242): 'ò', chr(243): 'ó',
|
||
|
|
chr(244): 'ô', chr(245): 'õ', chr(246): 'ö', chr(247): '÷',
|
||
|
|
chr(248): 'ø', chr(249): 'ù', chr(250): 'ú', chr(251): 'û',
|
||
|
|
chr(252): 'ü', chr(253): 'ý', chr(254): 'þ', chr(255): 'ÿ',
|
||
|
|
}
|
||
|
|
_html_ch = re.compile(r'['+reduce(lambda n, i: n+i, _html_enc.keys())+']')
|
||
|
|
def html_encode(o, also='', **kwargs):
|
||
|
|
'''Return HTML-encoded string.'''
|
||
|
|
o = _html_ch.sub(lambda match: _html_enc[match.group(0)], str(o))
|
||
|
|
for c in also:
|
||
|
|
try: r=_html_enc[c]
|
||
|
|
except: r='&#%d;' % ord(c)
|
||
|
|
o=o.replace(c, r)
|
||
|
|
return o
|
||
|
|
|
||
|
|
_url_ch = re.compile(r'[^A-Za-z0-9_.!~*()-]') # RFC 2396 section 2.3
|
||
|
|
def url_encode(o, **kwargs):
|
||
|
|
'''Return URL-encoded string.'''
|
||
|
|
return _url_ch.sub(lambda match: "%%%02X" % ord(match.group(0)), str(o))
|
||
|
|
|
||
|
|
_nb_space_ch = re.compile(' ')
|
||
|
|
def nb_space(o, **kwargs):
|
||
|
|
'''Return string with spaces converted to be non-breaking.'''
|
||
|
|
return _nb_space_ch.sub(lambda match: ' ', str(o))
|