aboutsummaryrefslogtreecommitdiff
path: root/system
diff options
context:
space:
mode:
authorAlTheKiller <AlTheKiller@svn>2009-09-23 01:49:50 +0000
committerAlTheKiller <AlTheKiller@svn>2009-09-23 01:49:50 +0000
commit45285e8a9300cd754a760560640b75b09f98035e (patch)
treead9f093885ad5c98e9dd4156674e7691c22ed0a2 /system
step 3/4: Move linuxport to trunk. How'd I get roped into this?
git-svn-id: https://xbmc.svn.sourceforge.net/svnroot/xbmc/trunk@23097 568bbfeb-2a22-0410-94d2-cc84cf5bfa90
Diffstat (limited to 'system')
-rw-r--r--system/IRSSmap.xml46
-rw-r--r--system/ImageLib.dllbin0 -> 1060864 bytes
-rw-r--r--system/ImageLib_raw.dllbin0 -> 569344 bytes
-rw-r--r--system/Lircmap.xml191
-rw-r--r--system/X10-Lola-IRSSmap.xml95
-rw-r--r--system/asound.conf177
-rwxr-xr-xsystem/cdrip/lame_enc-i486-linux.sobin0 -> 451388 bytes
-rwxr-xr-xsystem/cdrip/lame_enc-x86-osx.sobin0 -> 384348 bytes
-rw-r--r--system/cdrip/lame_enc.dllbin0 -> 387584 bytes
-rwxr-xr-xsystem/cdrip/ogg-i486-linux.sobin0 -> 16756 bytes
-rw-r--r--system/cdrip/ogg.dllbin0 -> 11264 bytes
-rwxr-xr-xsystem/cdrip/vorbis-i486-linux.sobin0 -> 164284 bytes
-rw-r--r--system/cdrip/vorbis.dllbin0 -> 991232 bytes
-rwxr-xr-xsystem/cdrip/vorbisenc-i486-linux.sobin0 -> 1018040 bytes
-rw-r--r--system/cdrip/vorbisenc.dllbin0 -> 884736 bytes
-rw-r--r--system/freetype6.dllbin0 -> 522240 bytes
-rw-r--r--system/hdhomerun.dllbin0 -> 101525 bytes
-rw-r--r--system/keymaps/gamepad.xml436
-rw-r--r--system/keymaps/joystick.AppleRemote.xml228
-rw-r--r--system/keymaps/joystick.Harmony.xml486
-rw-r--r--system/keymaps/joystick.Microsoft.Xbox.Controller.S.xml487
-rw-r--r--system/keymaps/joystick.Sony.PLAYSTATION(R)3.Controller.xml63
-rw-r--r--system/keymaps/joystick.WiiRemote.xml271
-rw-r--r--system/keymaps/keyboard.xml497
-rw-r--r--system/keymaps/remote.xml453
-rw-r--r--system/libcmyth.dllbin0 -> 1531904 bytes
-rwxr-xr-xsystem/libcurl-powerpc-osx.sobin0 -> 216568 bytes
-rwxr-xr-xsystem/libcurl-x86-osx.sobin0 -> 208644 bytes
-rw-r--r--system/libcurl.dllbin0 -> 622592 bytes
-rw-r--r--system/libexif.dllbin0 -> 12800 bytes
-rw-r--r--system/libid3tag.dllbin0 -> 98304 bytes
-rw-r--r--system/playercorefactory.xml37
-rw-r--r--system/players/dvdplayer/avcodec-52.dllbin0 -> 3887570 bytes
-rw-r--r--system/players/dvdplayer/avformat-52.dllbin0 -> 624911 bytes
-rw-r--r--system/players/dvdplayer/avutil-50.dllbin0 -> 117858 bytes
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/10-autohint.conf9
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/10-no-sub-pixel.conf9
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/10-sub-pixel-bgr.conf9
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/10-sub-pixel-rgb.conf9
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/10-sub-pixel-vbgr.conf9
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/10-sub-pixel-vrgb.conf9
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/10-unhinted.conf9
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/20-fix-globaladvance.conf29
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/20-lohit-gujarati.conf11
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/20-unhint-small-vera.conf49
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/30-amt-aliases.conf21
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/30-urw-aliases.conf52
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/40-generic.conf66
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/49-sansserif.conf21
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/50-user.conf7
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/51-local.conf7
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/60-latin.conf42
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/65-fonts-persian.conf539
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/65-nonlatin.conf38
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/69-unifont.conf24
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/70-no-bitmaps.conf13
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/70-yes-bitmaps.conf13
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/80-delicious.conf20
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/90-synthetic.conf64
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.avail/README48
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.d/20-fix-globaladvance.conf29
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.d/20-lohit-gujarati.conf11
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.d/20-unhint-small-vera.conf49
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.d/30-amt-aliases.conf21
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.d/30-urw-aliases.conf52
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.d/40-generic.conf66
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.d/49-sansserif.conf21
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.d/50-user.conf7
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.d/51-local.conf7
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.d/60-latin.conf42
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.d/65-fonts-persian.conf539
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.d/65-nonlatin.conf38
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.d/69-unifont.conf24
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.d/80-delicious.conf20
-rw-r--r--system/players/dvdplayer/etc/fonts/conf.d/90-synthetic.conf64
-rw-r--r--system/players/dvdplayer/etc/fonts/fonts.conf150
-rw-r--r--system/players/dvdplayer/etc/fonts/fonts.dtd222
-rw-r--r--system/players/dvdplayer/fontconfig_readme15
-rw-r--r--system/players/dvdplayer/freetype6.dllbin0 -> 514843 bytes
-rw-r--r--system/players/dvdplayer/liba52.dllbin0 -> 33280 bytes
-rw-r--r--system/players/dvdplayer/libass.dllbin0 -> 440832 bytes
-rw-r--r--system/players/dvdplayer/libdts.dllbin0 -> 146944 bytes
-rw-r--r--system/players/dvdplayer/libdvdcss-2.dllbin0 -> 54182 bytes
-rw-r--r--system/players/dvdplayer/libdvdnav.dllbin0 -> 234717 bytes
-rw-r--r--system/players/dvdplayer/libexpat.dllbin0 -> 147456 bytes
-rw-r--r--system/players/dvdplayer/libfaad.dllbin0 -> 249856 bytes
-rw-r--r--system/players/dvdplayer/libfontconfig-1.dllbin0 -> 218443 bytes
-rw-r--r--system/players/dvdplayer/libmad.dllbin0 -> 131072 bytes
-rw-r--r--system/players/dvdplayer/libmpeg2.dllbin0 -> 108544 bytes
-rw-r--r--system/players/dvdplayer/postproc-51.dllbin0 -> 63004 bytes
-rw-r--r--system/players/dvdplayer/swscale-0.6.1.dllbin0 -> 247248 bytes
-rw-r--r--system/players/paplayer/AACCodec.dllbin0 -> 241664 bytes
-rw-r--r--system/players/paplayer/AC3Codec.dllbin0 -> 33792 bytes
-rw-r--r--system/players/paplayer/MACDll.dllbin0 -> 143360 bytes
-rw-r--r--system/players/paplayer/NoseFart.dllbin0 -> 53248 bytes
-rwxr-xr-xsystem/players/paplayer/SNESAPU.DLLbin0 -> 45056 bytes
-rw-r--r--system/players/paplayer/StSoundLibrary.dllbin0 -> 57344 bytes
-rw-r--r--system/players/paplayer/adpcm.dllbin0 -> 6656 bytes
-rwxr-xr-xsystem/players/paplayer/adplug-i486-linux.sobin0 -> 2151094 bytes
-rw-r--r--system/players/paplayer/adplug.dllbin0 -> 167936 bytes
-rw-r--r--system/players/paplayer/dumb.dllbin0 -> 200704 bytes
-rw-r--r--system/players/paplayer/ffwma.dllbin0 -> 108032 bytes
-rw-r--r--system/players/paplayer/gensapu.dllbin0 -> 65536 bytes
-rw-r--r--system/players/paplayer/libFLAC.dllbin0 -> 155648 bytes
-rw-r--r--system/players/paplayer/libmpcdec.dllbin0 -> 37376 bytes
-rw-r--r--system/players/paplayer/libshnplay.dllbin0 -> 40960 bytes
-rw-r--r--system/players/paplayer/libsidplay2.dllbin0 -> 385024 bytes
-rw-r--r--system/players/paplayer/timidity.dllbin0 -> 555520 bytes
-rw-r--r--system/players/paplayer/vgmstream.dllbin0 -> 184320 bytes
-rw-r--r--system/players/paplayer/vorbisfile.dllbin0 -> 208896 bytes
-rw-r--r--system/players/paplayer/wavpack.dllbin0 -> 163840 bytes
-rwxr-xr-xsystem/players/paplayer/wma-i486-linux.sobin0 -> 154221 bytes
-rwxr-xr-xsystem/players/paplayer/xbmc_asap-i486-linux.sobin0 -> 114527 bytes
-rw-r--r--system/players/paplayer/xbmc_asap.dllbin0 -> 58368 bytes
-rwxr-xr-xsystem/python/DLLs/_socket.pydbin0 -> 49152 bytes
-rwxr-xr-xsystem/python/DLLs/_ssl.pydbin0 -> 483328 bytes
-rwxr-xr-xsystem/python/DLLs/bz2.pydbin0 -> 77824 bytes
-rwxr-xr-xsystem/python/DLLs/pyexpat.pydbin0 -> 135168 bytes
-rwxr-xr-xsystem/python/DLLs/select.pydbin0 -> 7680 bytes
-rwxr-xr-xsystem/python/DLLs/unicodedata.pydbin0 -> 405504 bytes
-rwxr-xr-xsystem/python/DLLs/zlib.pydbin0 -> 69632 bytes
-rw-r--r--system/python/python24.dllbin0 -> 1871872 bytes
-rw-r--r--system/python/python24.zlibbin0 -> 1394340 bytes
-rw-r--r--system/python/readme.txt16
-rw-r--r--system/python/spyce/CHANGES566
-rw-r--r--system/python/spyce/Cookie.py557
-rw-r--r--system/python/spyce/LICENCE40
-rw-r--r--system/python/spyce/README15
-rw-r--r--system/python/spyce/RELEASE21
-rw-r--r--system/python/spyce/THANKS57
-rw-r--r--system/python/spyce/fcgi.py265
-rw-r--r--system/python/spyce/installHelper.py181
-rw-r--r--system/python/spyce/makefile160
-rw-r--r--system/python/spyce/modules/automaton.py79
-rw-r--r--system/python/spyce/modules/compress.py84
-rw-r--r--system/python/spyce/modules/cookie.py50
-rw-r--r--system/python/spyce/modules/error.py171
-rw-r--r--system/python/spyce/modules/include.py117
-rw-r--r--system/python/spyce/modules/pool.py45
-rw-r--r--system/python/spyce/modules/redirect.py53
-rw-r--r--system/python/spyce/modules/request.py224
-rw-r--r--system/python/spyce/modules/response.py186
-rw-r--r--system/python/spyce/modules/session.py368
-rw-r--r--system/python/spyce/modules/spylambda.py55
-rw-r--r--system/python/spyce/modules/stdout.py104
-rw-r--r--system/python/spyce/modules/taglib.py102
-rw-r--r--system/python/spyce/modules/template.py68
-rw-r--r--system/python/spyce/modules/toc.py240
-rw-r--r--system/python/spyce/modules/transform.py155
-rwxr-xr-xsystem/python/spyce/run_spyceCGI.py21
-rwxr-xr-xsystem/python/spyce/run_spyceCmd.py22
-rwxr-xr-xsystem/python/spyce/run_spyceModpy.py49
-rw-r--r--system/python/spyce/spyce.conf162
-rw-r--r--system/python/spyce/spyce.mime495
-rw-r--r--system/python/spyce/spyce.nsi208
-rw-r--r--system/python/spyce/spyce.nsi.in208
-rwxr-xr-xsystem/python/spyce/spyce.py674
-rw-r--r--system/python/spyce/spyce.spec.in74
-rw-r--r--system/python/spyce/spyceApache.conf76
-rwxr-xr-xsystem/python/spyce/spyceCGI.py48
-rw-r--r--system/python/spyce/spyceCache.py152
-rwxr-xr-xsystem/python/spyce/spyceCmd.py336
-rw-r--r--system/python/spyce/spyceCompile.py1111
-rw-r--r--system/python/spyce/spyceConfig.py370
-rw-r--r--system/python/spyce/spyceException.py116
-rw-r--r--system/python/spyce/spyceLock.py120
-rw-r--r--system/python/spyce/spyceModpy.py138
-rw-r--r--system/python/spyce/spyceModule.py55
-rw-r--r--system/python/spyce/spyceTag.py260
-rw-r--r--system/python/spyce/spyceUtil.py157
-rw-r--r--system/python/spyce/spyceWWW.py324
-rw-r--r--system/python/spyce/spyceXbmc.py25
-rw-r--r--system/python/spyce/tree.py70
-rwxr-xr-xsystem/python/spyce/verchk.py36
-rw-r--r--system/scrapers/music/allmusic.gifbin0 -> 2623 bytes
-rw-r--r--system/scrapers/music/allmusic.xml84
-rw-r--r--system/scrapers/music/allmusic_merlin_lastfm.xml149
-rw-r--r--system/scrapers/music/common/allmusic.xml141
-rw-r--r--system/scrapers/music/common/htbackdrops.xml18
-rw-r--r--system/scrapers/music/common/lastfm.xml10
-rw-r--r--system/scrapers/music/discogs.gifbin0 -> 1423 bytes
-rw-r--r--system/scrapers/music/discogs.xml127
-rw-r--r--system/scrapers/music/freebase.pngbin0 -> 9930 bytes
-rw-r--r--system/scrapers/music/freebase.xml149
-rw-r--r--system/scrapers/music/israel-music.pngbin0 -> 2178 bytes
-rw-r--r--system/scrapers/music/israel-music.xml53
-rw-r--r--system/scrapers/music/lastfm.xml121
-rw-r--r--system/scrapers/video/AdultFilmdatabase.gifbin0 -> 1174 bytes
-rw-r--r--system/scrapers/video/Excalibur.jpgbin0 -> 19904 bytes
-rw-r--r--system/scrapers/video/Excalibur.xml65
-rw-r--r--system/scrapers/video/KinoPoisk.gifbin0 -> 1899 bytes
-rw-r--r--system/scrapers/video/KinoPoisk.xml342
-rw-r--r--system/scrapers/video/MyMovies.pngbin0 -> 4468 bytes
-rw-r--r--system/scrapers/video/MyMovies.xml333
-rw-r--r--system/scrapers/video/adultcdmovies.jpgbin0 -> 4489 bytes
-rw-r--r--system/scrapers/video/adultcdmovies.xml67
-rw-r--r--system/scrapers/video/adultdvdempire.jpgbin0 -> 7426 bytes
-rw-r--r--system/scrapers/video/adultdvdempire.xml76
-rw-r--r--system/scrapers/video/adultfilmdatabase.xml61
-rw-r--r--system/scrapers/video/allocine.jpgbin0 -> 5750 bytes
-rw-r--r--system/scrapers/video/allocine.xml204
-rw-r--r--system/scrapers/video/amazonuk.pngbin0 -> 31789 bytes
-rw-r--r--system/scrapers/video/amazonuk.xml154
-rw-r--r--system/scrapers/video/amazonus.pngbin0 -> 18812 bytes
-rw-r--r--system/scrapers/video/amazonus.xml125
-rw-r--r--system/scrapers/video/asiandb.gifbin0 -> 4133 bytes
-rw-r--r--system/scrapers/video/asiandb.xml103
-rw-r--r--system/scrapers/video/cinefacts.pngbin0 -> 21467 bytes
-rw-r--r--system/scrapers/video/cinefacts.xml134
-rw-r--r--system/scrapers/video/common/dtrailer.xml15
-rw-r--r--system/scrapers/video/common/imdb.xml74
-rw-r--r--system/scrapers/video/common/impa.xml24
-rw-r--r--system/scrapers/video/common/movieposterdb.xml15
-rw-r--r--system/scrapers/video/common/tmdb.xml40
-rw-r--r--system/scrapers/video/culturalia.gifbin0 -> 2012 bytes
-rw-r--r--system/scrapers/video/culturalia.xml115
-rw-r--r--system/scrapers/video/daum.pngbin0 -> 3050 bytes
-rw-r--r--system/scrapers/video/daum.xml183
-rw-r--r--system/scrapers/video/fdbpl.pngbin0 -> 10930 bytes
-rw-r--r--system/scrapers/video/fdbpl.xml170
-rw-r--r--system/scrapers/video/filmaffinity.gifbin0 -> 6896 bytes
-rw-r--r--system/scrapers/video/filmaffinity.xml283
-rw-r--r--system/scrapers/video/filmdelta.pngbin0 -> 13189 bytes
-rw-r--r--system/scrapers/video/filmdelta.xml90
-rw-r--r--system/scrapers/video/filmstarts.jpgbin0 -> 10506 bytes
-rw-r--r--system/scrapers/video/filmstarts.xml159
-rw-r--r--system/scrapers/video/filmup.gifbin0 -> 4499 bytes
-rw-r--r--system/scrapers/video/filmup.xml85
-rw-r--r--system/scrapers/video/filmweb.jpgbin0 -> 13615 bytes
-rw-r--r--system/scrapers/video/filmweb.xml194
-rw-r--r--system/scrapers/video/imdb tv.xml218
-rw-r--r--system/scrapers/video/imdb-cn.gifbin0 -> 4690 bytes
-rw-r--r--system/scrapers/video/imdb-cn.xml137
-rw-r--r--system/scrapers/video/imdb.pngbin0 -> 22110 bytes
-rw-r--r--system/scrapers/video/imdb.xml159
-rw-r--r--system/scrapers/video/jaded.jpgbin0 -> 4870 bytes
-rw-r--r--system/scrapers/video/jadedVideo.xml47
-rw-r--r--system/scrapers/video/moviemaze.jpgbin0 -> 4784 bytes
-rw-r--r--system/scrapers/video/moviemaze.xml174
-rw-r--r--system/scrapers/video/mtime.jpgbin0 -> 12439 bytes
-rw-r--r--system/scrapers/video/mtime.xml137
-rw-r--r--system/scrapers/video/mtv.pngbin0 -> 14920 bytes
-rw-r--r--system/scrapers/video/mtv.xml42
-rw-r--r--system/scrapers/video/musicvideos.xml37
-rw-r--r--system/scrapers/video/mymoviesdk.pngbin0 -> 12892 bytes
-rw-r--r--system/scrapers/video/mymoviesdk.xml188
-rw-r--r--system/scrapers/video/naver.pngbin0 -> 15145 bytes
-rw-r--r--system/scrapers/video/naver.xml180
-rw-r--r--system/scrapers/video/ofdb.pngbin0 -> 12693 bytes
-rw-r--r--system/scrapers/video/ofdb.xml261
-rw-r--r--system/scrapers/video/ofdbxml.xml129
-rw-r--r--system/scrapers/video/ptgate.jpgbin0 -> 6495 bytes
-rw-r--r--system/scrapers/video/ptgate.xml280
-rw-r--r--system/scrapers/video/speedallocinev2.xml28
-rw-r--r--system/scrapers/video/sratim.gifbin0 -> 4617 bytes
-rw-r--r--system/scrapers/video/sratim.xml115
-rw-r--r--system/scrapers/video/tmdb.pngbin0 -> 21456 bytes
-rw-r--r--system/scrapers/video/tmdb.xml99
-rw-r--r--system/scrapers/video/tvcom.pngbin0 -> 4029 bytes
-rw-r--r--system/scrapers/video/tvcom.xml110
-rw-r--r--system/scrapers/video/tvdb.pngbin0 -> 3932 bytes
-rw-r--r--system/scrapers/video/tvdb.xml304
-rw-r--r--system/scrapers/video/tvrage.jpgbin0 -> 6837 bytes
-rw-r--r--system/scrapers/video/tvrage.xml100
-rw-r--r--system/scrapers/video/worldart.gifbin0 -> 5205 bytes
-rw-r--r--system/scrapers/video/worldart.xml256
-rw-r--r--system/scrapers/video/yahoomusic.pngbin0 -> 8629 bytes
-rw-r--r--system/scrapers/video/yahoomusic.xml50
-rw-r--r--system/shaders/yuv2rgb_basic.glsl28
-rw-r--r--system/shaders/yuv2rgb_basic_2d.arb13
-rw-r--r--system/shaders/yuv2rgb_basic_rect.arb13
-rw-r--r--system/shaders/yuv2rgb_bob.glsl44
-rw-r--r--system/shaders/yuv2rgb_vertex.glsl18
273 files changed, 22387 insertions, 0 deletions
diff --git a/system/IRSSmap.xml b/system/IRSSmap.xml
new file mode 100644
index 0000000000..42c623a447
--- /dev/null
+++ b/system/IRSSmap.xml
@@ -0,0 +1,46 @@
+<!-- This file contains the mapping of IR Server Suite keys to XBMC keys used in Keymap.xml -->
+
+<irssmap>
+ <remote device="Microsoft MCE">
+ <pause>31719</pause> <!-- pause -->
+ <stop>31718</stop> <!-- stop -->
+ <play>31721</play> <!-- play -->
+ <forward>31723</forward> <!-- forward -->
+ <reverse>31722</reverse> <!-- reverse -->
+ <left>31711</left> <!-- left -->
+ <right>31710</right> <!-- right -->
+ <up>31713</up> <!-- up -->
+ <down>31712</down> <!-- down -->
+ <select>31709</select> <!-- ok -->
+ <pageplus>31725</pageplus> <!-- channel up -->
+ <pageminus>31724</pageminus> <!-- channel down -->
+ <back>31708</back> <!-- previous -->
+ <menu>31707</menu> <!-- dvd menu -->
+ <title>31671</title> <!-- recorded tv -->
+ <info>31728</info> <!-- info -->
+ <skipplus>31717</skipplus> <!-- skip -->
+ <skipminus>31716</skipminus> <!-- repeat -->
+ <display>31705</display> <!-- guide -->
+ <start>31730</start> <!-- start -->
+ <record>31720</record> <!-- record -->
+ <volumeplus>31727</volumeplus> <!-- volume up -->
+ <volumeminus>31726</volumeminus> <!-- volume down -->
+ <mute>31729</mute> <!-- mute -->
+ <power>31642</power> <!-- tv power -->
+ <mytv>31706</mytv> <!-- live tv -->
+ <one>31742</one>
+ <two>31741</two>
+ <three>31740</three>
+ <four>31739</four>
+ <five>31738</five>
+ <six>31737</six>
+ <seven>31736</seven>
+ <eight>31735</eight>
+ <nine>31734</nine>
+ <zero>31743</zero>
+ <mytv>31652</mytv> <!-- red -->
+ <mymusic>31651</mymusic> <!-- green -->
+ <mypictures>31650</mypictures> <!-- yellow -->
+ <myvideo>31649</myvideo> <!-- blue -->
+ </remote>
+</irssmap>
diff --git a/system/ImageLib.dll b/system/ImageLib.dll
new file mode 100644
index 0000000000..be8f3d1978
--- /dev/null
+++ b/system/ImageLib.dll
Binary files differ
diff --git a/system/ImageLib_raw.dll b/system/ImageLib_raw.dll
new file mode 100644
index 0000000000..35f89e18e4
--- /dev/null
+++ b/system/ImageLib_raw.dll
Binary files differ
diff --git a/system/Lircmap.xml b/system/Lircmap.xml
new file mode 100644
index 0000000000..617964da2e
--- /dev/null
+++ b/system/Lircmap.xml
@@ -0,0 +1,191 @@
+<!-- This file contains the mapping of LIRC keys to XBMC keys used in Keymap.xml -->
+<!-- -->
+<!-- How to add remotes -->
+<!-- <remote device="name_Lirc_calls_the_remote"> -->
+<!-- -->
+<!-- For the commands the layout following layout is used -->
+<!-- <XBMC_COMMAND>LircButtonName</XBMC_COMMAND> -->
+<!-- -->
+<!-- For a list of XBMC_COMMAND's check out the <remote> sections of keymap.xml -->
+
+<lircmap>
+ <remote device="mceusb">
+ <pause>Pause</pause>
+ <stop>Stop</stop>
+ <forward>Forward</forward>
+ <reverse>Rewind</reverse>
+ <left>Left</left>
+ <right>Right</right>
+ <up>Up</up>
+ <down>Down</down>
+ <select>OK</select>
+ <pageplus>ChanUp</pageplus>
+ <pageminus>ChanDown</pageminus>
+ <back>Back</back>
+ <menu>PreviousMenu</menu>
+ <title>Play</title>
+ <info>More</info>
+ <skipplus>Skip</skipplus>
+ <skipminus>Replay</skipminus>
+ <display>Teletext</display>
+ <start>Home</start>
+ <record>Record</record>
+ <volumeplus>VolUp</volumeplus>
+ <volumeminus>VolDown</volumeminus>
+ <mute>Mute</mute>
+ <power>Power</power>
+ <myvideo>Videos</myvideo>
+ <mymusic>Music</mymusic>
+ <mypictures>Pictures</mypictures>
+ <mytv>TV</mytv>
+ <one>One</one>
+ <two>Two</two>
+ <three>Three</three>
+ <four>Four</four>
+ <five>Five</five>
+ <six>Six</six>
+ <seven>Seven</seven>
+ <eight>Eight</eight>
+ <nine>Nine</nine>
+ <zero>Zero</zero>
+ <mytv>Red</mytv>
+ <mymusic>Green</mymusic>
+ <mypictures>Yellow</mypictures>
+ <myvideo>Blue</myvideo>
+ </remote>
+
+ <remote device="XboxDVDDongle">
+ <play>PLAY</play>
+ <pause>PAUSE</pause>
+ <stop>STOP</stop>
+ <forward>FORWARD</forward>
+ <reverse>REVERSE</reverse>
+ <left>LEFT</left>
+ <right>RIGHT</right>
+ <up>UP</up>
+ <down>DOWN</down>
+ <select>SELECT</select>
+ <back>BACK</back>
+ <menu>MENU</menu>
+ <title>TITLE</title>
+ <info>INFO</info>
+ <skipplus>SKIP+</skipplus>
+ <skipminus>SKIP-</skipminus>
+ <display>DISPLAY</display>
+ <one>1</one>
+ <two>2</two>
+ <three>3</three>
+ <four>4</four>
+ <five>5</five>
+ <six>6</six>
+ <seven>7</seven>
+ <eight>8</eight>
+ <nine>9</nine>
+ <zero>0</zero>
+ </remote>
+
+ <remote device="Microsoft_Xbox">
+ <play>PLAY</play>
+ <pause>PAUSE</pause>
+ <stop>STOP</stop>
+ <forward>FORWARD</forward>
+ <reverse>REVERSE</reverse>
+ <left>LEFT</left>
+ <right>RIGHT</right>
+ <up>UP</up>
+ <down>DOWN</down>
+ <select>SELECT</select>
+ <back>BACK</back>
+ <menu>MENU</menu>
+ <title>TITLE</title>
+ <info>INFO</info>
+ <skipplus>SKIP+</skipplus>
+ <skipminus>SKIP-</skipminus>
+ <display>DISPLAY</display>
+ <one>1</one>
+ <two>2</two>
+ <three>3</three>
+ <four>4</four>
+ <five>5</five>
+ <six>6</six>
+ <seven>7</seven>
+ <eight>8</eight>
+ <nine>9</nine>
+ <zero>0</zero>
+ </remote>
+
+ <remote device="PinnacleSysPCTVRemote">
+ <play>Play</play>
+ <pause>pause</pause>
+ <stop>Stop</stop>
+ <forward>FForward</forward>
+ <reverse>Rewind</reverse>
+ <left>Vol-Rew</left>
+ <right>Vol+FF</right>
+ <up>Chan+Play</up>
+ <down>Chan-Stop</down>
+ <pageplus>channel+</pageplus>
+ <pageminus>channel-</pageminus>
+ <select>middle</select>
+ <back>undo</back>
+ <menu>Menu</menu>
+ <title>L</title>
+ <info>Info</info>
+ <skipplus>next</skipplus>
+ <display>Fullscreen</display>
+ <record>Record</record>
+ <volumeplus>vol+</volumeplus>
+ <volumeminus>vol-</volumeminus>
+ <mute>Mute</mute>
+ <power>Power</power>
+ <one>1</one>
+ <two>2</two>
+ <three>3</three>
+ <four>4</four>
+ <five>5</five>
+ <six>6</six>
+ <seven>7</seven>
+ <eight>8</eight>
+ <nine>9</nine>
+ <zero>0</zero>
+ </remote>
+
+ <remote device="anysee">
+ <pause>pause</pause>
+ <stop>stop</stop>
+ <forward>f1</forward>
+ <reverse>f2</reverse>
+ <left>left</left>
+ <right>right</right>
+ <up>chan-up</up>
+ <down>chan-down</down>
+ <select>ok</select>
+ <back>exit</back>
+ <menu>menu</menu>
+ <title>play</title>
+ <info>info</info>
+ <skipplus>jump-fwd</skipplus>
+ <skipminus>jump-back</skipminus>
+ <display>size</display>
+ <start>star</start>
+ <record>rec</record>
+ <volumeplus></volumeplus>
+ <volumeminus></volumeminus>
+ <mute>mute</mute>
+ <power>power</power>
+ <one>1</one>
+ <two>2</two>
+ <three>3</three>
+ <four>4</four>
+ <five>5</five>
+ <six>6</six>
+ <seven>7</seven>
+ <eight>8</eight>
+ <nine>9</nine>
+ <zero>0</zero>
+ <mytv>red</mytv>
+ <mymusic>green</mymusic>
+ <mypictures>yellow</mypictures>
+ <myvideo>blue</myvideo>
+ </remote>
+</lircmap>
diff --git a/system/X10-Lola-IRSSmap.xml b/system/X10-Lola-IRSSmap.xml
new file mode 100644
index 0000000000..ab6b00eaba
--- /dev/null
+++ b/system/X10-Lola-IRSSmap.xml
@@ -0,0 +1,95 @@
+<!-- X10 Lola UR89A in PC MODE
+Button = CMD
+Record = X10CMD_RECORD
+Stop = X10CMD_STOP
+Pause = X10CMD_NONE
+Scan- = X10CMD_INPUT
+Rew = X10CMD_REWIND
+Play = X10CMD_PLAY
+FF = X10CMD_FF
+Scan+ = X10CMD_ZOOM
+Top = X10CMD_MTRADIO
+End = X10CMD_MTPC
+Find = X10CMD_HANDSYMBOL
+Select = X10CMD_MTCHANNELLIST
+Page Up = X10CMD_BOOKMARK
+Page Dn = X10CMD_RESIZE
+Playlist = X10CMD_BUTTON_B
+Playing = X10CMD_MTVCR
+Left = X10CMD_LEFT
+Right = X10CMD_RIGHT
+Up = X10CMD_UP
+Down = X10CMD_DN
+Enter = X10CMD_ENTER
+Album = X10CMD_BUTTON_C
+Artist = X10CMD_BUTTON_D
+Genre = X10CMD_BUTTON_E
+Track = X10CMD_BUTTON_F
+1 = X10CMD_1
+2 = X10CMD_2
+3 = X10CMD_3
+4 = X10CMD_4
+5 = X10CMD_5
+6 = X10CMD_6
+7 = X10CMD_7
+8 = X10CMD_8
+9 = X10CMD_9
+0 = X10CMD_0
+Add/Del = X10CMD_MTADDDELETE
+A/B = X10CMT_MTAB
+Vol Left = X10CMD_VOL_UP (this button is actually labeled Vol-)
+Vol Right = X10CMD_VOL_DN (this button is actually labeled Vol+)
+Chan Up = X10CMD_CH_UP
+Chan Down = X10CMD_CH_DN
+M/All Off = X10CMD_MUTE
+Power/All Lts On = X10CMD_POWER
+ -->
+<irssmap>
+ <remote device="X10">
+ <pause>X10CMD_NONE</pause> <!-- Pause -->
+ <stop>X10CMD_STOP</stop> <!-- Stop -->
+ <play>X10CMD_PLAY</play> <!-- Play -->
+ <forward>X10CMD_FF</forward> <!-- FF -->
+ <reverse>X10CMD_REWIND</reverse> <!-- Rew -->
+ <left>X10CMD_LEFT</left> <!-- Left -->
+ <right>X10CMD_RIGHT</right> <!-- Right -->
+ <up>X10CMD_UP</up> <!-- Up -->
+ <down>X10CMD_DN</down> <!-- Down -->
+ <select>X10CMD_ENTER</select> <!-- Enter -->
+ <pageplus>X10CMD_BOOKMARK</pageplus> <!-- Page Up -->
+ <pageminus>X10CMD_RESIZE</pageminus> <!-- Page Down -->
+ <back>X10CMD_MTAB</back> <!-- A/B -->
+ <menu>X10CMD_MTRADIO</menu> <!-- Top -->
+ <title>X10CMD_MTPC</title> <!-- End -->
+ <info>X10CMD_HANDSYMBOL</info> <!-- Find -->
+ <skipplus>X10CMD_INPUT</skipplus> <!-- Scan- -->
+ <skipminus>X10CMD_ZOOM</skipminus> <!-- Scan+ -->
+ <display>X10CMD_MTVCR</display> <!-- Playing -->
+ <start>X10CMD_MTCHANNELLIST</start> <!-- Select -->
+ <record>X10CMD_RECORD</record> <!-- Rec -->
+ <mute>X10CMD_MUTE</mute> <!-- M/All off -->
+ <power>X10CMD_POWER</power> <!-- Power/All Lts on -->
+ <one>X10CMD_1</one> <!-- 1 -->
+ <two>X10CMD_2</two> <!-- 2 -->
+ <three>X10CMD_3</three> <!-- 3 -->
+ <four>X10CMD_4</four> <!-- 4 -->
+ <five>X10CMD_5</five> <!-- 5 -->
+ <six>X10CMD_6</six> <!-- 6 -->
+ <seven>X10CMD_7</seven> <!-- 7 -->
+ <eight>X10CMD_8</eight> <!-- 8 -->
+ <nine>X10CMD_9</nine> <!-- 9 -->
+ <zero>X10CMD_0</zero> <!-- 0 -->
+ <channelplus>X10CMD_CH_UP</channelplus> <!-- CH+ -->
+ <channelminus>X10CMD_CH_DN</channelminus> <!-- CH- -->
+ <volumeplus>X10CMD_VOL_DN</volumeplus> <!-- VOL+ (volume commands are reversed) -->
+ <volumeminus>X10CMD_VOL_UP</volumeminus> <!-- VOL- (volume commands are reversed) -->
+ <livetv>X10CMD_BUTTON_B</livetv> <!-- Playlist -->
+ <star></star>
+ <hash></hash>
+ <clear>X10CMD_MTADDDELETE</clear> <!-- Add/Delete -->
+ <mytv></mytv>
+ <mymusic></mymusic>
+ <mypictures></mypictures>
+ <myvideo></myvideo>
+ </remote>
+</irssmap>
diff --git a/system/asound.conf b/system/asound.conf
new file mode 100644
index 0000000000..45ddb1e9fd
--- /dev/null
+++ b/system/asound.conf
@@ -0,0 +1,177 @@
+
+# Linux has channel order
+# FL, FR, SL, SR, C, LFE
+# so we remap all channelorders to this
+
+# Windows - FL, FR, C, LFE, BL, BR, (FLC, FRC, BC, SL, SR, TC, TFL, TFC, TFR, TBL, TBC, TBR)
+pcm.xbmc_win51 {
+ @args.0 SLAVE
+ @args.SLAVE {
+ type string
+ default "default"
+ }
+ type route
+ slave {
+ pcm $SLAVE
+ channels 6
+ }
+ ttable {
+ 0.0= 1
+ 1.1= 1
+ 2.4= 1
+ 3.5= 1
+ 4.2= 1
+ 5.3= 1
+ }
+}
+
+pcm.xbmc_win50 {
+ @args.0 SLAVE
+ @args.SLAVE {
+ type string
+ default "default"
+ }
+ type route
+ slave {
+ pcm $SLAVE
+ channels 5
+ }
+ ttable {
+ 0.0= 1
+ 1.1= 1
+ 2.4= 1
+ 3.2= 1
+ 4.3= 1
+ }
+}
+
+# FL, C, FR, SL, SR, LFE
+pcm.xbmc_ogg51 {
+ @args.0 SLAVE
+ @args.SLAVE {
+ type string
+ default "default"
+ }
+ type route
+ slave {
+ pcm $SLAVE
+ channels 6
+ }
+ ttable {
+ 0.0= 1
+ 1.4= 1
+ 2.1= 1
+ 3.2= 1
+ 4.3= 1
+ 5.5= 1
+ }
+}
+
+pcm.xbmc_ogg50 {
+ @args.0 SLAVE
+ @args.SLAVE {
+ type string
+ default "default"
+ }
+ type route
+ slave {
+ pcm $SLAVE
+ channels 5
+ }
+ ttable {
+ 0.0= 1
+ 1.4= 1
+ 2.1= 1
+ 3.2= 1
+ 4.3= 1
+ }
+}
+
+# C, FL, FR, SL, SR, LFE
+pcm.xbmc_aac51 {
+ @args.0 SLAVE
+ @args.SLAVE {
+ type string
+ default "default"
+ }
+ type route
+ slave {
+ pcm $SLAVE
+ channels 6
+ }
+ ttable {
+ 0.4= 1
+ 1.0= 1
+ 2.1= 1
+ 3.2= 1
+ 4.3= 1
+ 5.5= 1
+ }
+}
+
+pcm.xbmc_aac50 {
+ @args.0 SLAVE
+ @args.SLAVE {
+ type string
+ default "default"
+ }
+ type route
+ slave {
+ pcm $SLAVE
+ channels 6
+ }
+ ttable {
+ 0.4= 1
+ 1.0= 1
+ 2.1= 1
+ 3.2= 1
+ 4.3= 1
+ }
+}
+
+# this could potentially be used to encode multichannels
+# to ac3 for passthrough out an spdif
+pcm.xbmc_a52encode {
+ type a52
+}
+
+# downmixing to 2 channels
+pcm.xbmc_51to2 {
+ @args.0 SLAVE
+ @args.SLAVE {
+ type string
+ default "default"
+ }
+ type plug
+ slave.pcm $SLAVE
+ slave.channels 2
+ route_policy duplicate
+ ttable.0.0 1 # front left speaker
+ ttable.1.1 1 # front right speaker
+ ttable.2.0 0.7 # rear left speaker
+ ttable.3.1 0.7 # rear right speaker
+ ttable.4.0 0.7 # center to left mapping
+ ttable.4.1 0.7 # center to right mapping
+ ttable.5.0 0.5 # LFE (base) to left mapping
+ ttable.5.1 0.5 # LFE to right mapping
+}
+
+# downmixing to 2 channels
+pcm.xbmc_50to2 {
+ @args.0 SLAVE
+ @args.SLAVE {
+ type string
+ default "default"
+ }
+ type plug
+ slave.pcm $SLAVE
+ slave.channels 2
+ route_policy duplicate
+ ttable.0.0 1 # front left speaker
+ ttable.1.1 1 # front right speaker
+ ttable.2.0 0.7 # rear left speaker
+ ttable.3.1 0.7 # rear right speaker
+ ttable.4.0 0.7 # center to left mapping
+ ttable.4.1 0.7 # center to right mapping
+}
+
diff --git a/system/cdrip/lame_enc-i486-linux.so b/system/cdrip/lame_enc-i486-linux.so
new file mode 100755
index 0000000000..f018c37dbd
--- /dev/null
+++ b/system/cdrip/lame_enc-i486-linux.so
Binary files differ
diff --git a/system/cdrip/lame_enc-x86-osx.so b/system/cdrip/lame_enc-x86-osx.so
new file mode 100755
index 0000000000..a39110c579
--- /dev/null
+++ b/system/cdrip/lame_enc-x86-osx.so
Binary files differ
diff --git a/system/cdrip/lame_enc.dll b/system/cdrip/lame_enc.dll
new file mode 100644
index 0000000000..46dbdcbec0
--- /dev/null
+++ b/system/cdrip/lame_enc.dll
Binary files differ
diff --git a/system/cdrip/ogg-i486-linux.so b/system/cdrip/ogg-i486-linux.so
new file mode 100755
index 0000000000..b9e557a6ad
--- /dev/null
+++ b/system/cdrip/ogg-i486-linux.so
Binary files differ
diff --git a/system/cdrip/ogg.dll b/system/cdrip/ogg.dll
new file mode 100644
index 0000000000..c393ff0a15
--- /dev/null
+++ b/system/cdrip/ogg.dll
Binary files differ
diff --git a/system/cdrip/vorbis-i486-linux.so b/system/cdrip/vorbis-i486-linux.so
new file mode 100755
index 0000000000..039d2a3b2d
--- /dev/null
+++ b/system/cdrip/vorbis-i486-linux.so
Binary files differ
diff --git a/system/cdrip/vorbis.dll b/system/cdrip/vorbis.dll
new file mode 100644
index 0000000000..acaee1629e
--- /dev/null
+++ b/system/cdrip/vorbis.dll
Binary files differ
diff --git a/system/cdrip/vorbisenc-i486-linux.so b/system/cdrip/vorbisenc-i486-linux.so
new file mode 100755
index 0000000000..9596bd738d
--- /dev/null
+++ b/system/cdrip/vorbisenc-i486-linux.so
Binary files differ
diff --git a/system/cdrip/vorbisenc.dll b/system/cdrip/vorbisenc.dll
new file mode 100644
index 0000000000..0b947f9713
--- /dev/null
+++ b/system/cdrip/vorbisenc.dll
Binary files differ
diff --git a/system/freetype6.dll b/system/freetype6.dll
new file mode 100644
index 0000000000..e35edc6bb0
--- /dev/null
+++ b/system/freetype6.dll
Binary files differ
diff --git a/system/hdhomerun.dll b/system/hdhomerun.dll
new file mode 100644
index 0000000000..cb9c9a8368
--- /dev/null
+++ b/system/hdhomerun.dll
Binary files differ
diff --git a/system/keymaps/gamepad.xml b/system/keymaps/gamepad.xml
new file mode 100644
index 0000000000..6e736ff72d
--- /dev/null
+++ b/system/keymaps/gamepad.xml
@@ -0,0 +1,436 @@
+<!-- This file contains the mapping of keys (gamepad, remote, and keyboard) to actions within XBMC -->
+<!-- The <global> section is a fall through - they will only be used if the button is not -->
+<!-- used in the current window's section. Note that there is only handling -->
+<!-- for a single action per button at this stage. -->
+<!-- For joystick/gamepad configuration under linux/win32, see below as it differs from xbox -->
+<!-- gamepads. -->
+
+<!-- The format is: -->
+<!-- <device> -->
+<!-- <button>action</button> -->
+<!-- </device> -->
+
+<!-- To map keys from other remotes using the RCA protocol, you may add <universalremote> blocks -->
+<!-- In this case, the tags used are <obc#> where # is the original button code (OBC) of the key -->
+<!-- You set it up by adding a <universalremote> block to the window or <global> section: -->
+<!-- <universalremote> -->
+<!-- <obc45>Stop</obc45> -->
+<!-- </universalremote> -->
+<!-- To find out the OBC's of your remote, try enabling the <displayremotecodes> tag in AdvancedSettings.xml -->
+
+<!-- Note that the action can be a built-in function. -->
+<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> -->
+<!-- would automatically go to My Music on the press of the B button. -->
+
+<!-- Joysticks / Gamepads: -->
+<!-- See the sample PS3 controller configuration below for the format. -->
+<!-- -->
+<!-- Joystick Name: -->
+<!-- Do 'cat /proc/bus/input/devices' or see your xbmc log file to find the names of -->
+<!-- detected joysticks. The name used in the configuration should match the detected name. -->
+<!-- -->
+<!-- Button Ids: -->
+<!-- 'id' is the button ID used by SDL. Joystick button ids of connected joysticks appear -->
+<!-- in xbmc.log when they are pressed. Use your log to map custom buttons to actions. -->
+<!-- -->
+<!-- Axis Ids / Analog Controls -->
+<!-- Coming soon. -->
+<keymap>
+ <global>
+ <gamepad>
+ <A>Select</A>
+ <B>ParentDir</B>
+ <X>FullScreen</X>
+ <Y>Queue</Y>
+ <white>ContextMenu</white>
+ <black/>
+ <start>XBMC.ActivateWindow(PlayerControls)</start>
+ <back>PreviousMenu</back>
+ <dpadleft>Left</dpadleft>
+ <dpadright>Right</dpadright>
+ <dpadup>Up</dpadup>
+ <dpaddown>Down</dpaddown>
+ <leftthumbbutton>Screenshot</leftthumbbutton>
+ <rightthumbbutton>XBMC.ActivateWindow(ShutdownMenu)</rightthumbbutton>
+ <leftanalogtrigger>ScrollUp</leftanalogtrigger>
+ <rightanalogtrigger>ScrollDown</rightanalogtrigger>
+ <rightthumbstickleft>AnalogSeekBack</rightthumbstickleft>
+ <rightthumbstickright>AnalogSeekForward</rightthumbstickright>
+ <rightthumbstickup>VolumeUp</rightthumbstickup>
+ <rightthumbstickdown>VolumeDown</rightthumbstickdown>
+ </gamepad>
+ </global>
+ <Home>
+ <gamepad>
+ <black>XBMC.Skin.ToggleSetting(HomeViewToggle)</black>
+ </gamepad>
+ </Home>
+ <MyFiles>
+ <gamepad>
+ <Y>Highlight</Y>
+ </gamepad>
+ </MyFiles>
+ <MyMusicPlaylist>
+ <gamepad>
+ <Y>Delete</Y>
+ <black>Playlist</black> <!-- Close playlist -->
+ <back>Playlist</back> <!-- Close playlist -->
+ <B>Playlist</B> <!-- Close playlist -->
+ </gamepad>
+ </MyMusicPlaylist>
+ <MyMusicPlaylistEditor>
+ <gamepad>
+ <Y>Queue</Y>
+ </gamepad>
+ </MyMusicPlaylistEditor>
+ <MyMusicFiles>
+ <gamepad>
+ <Y>Queue</Y>
+ <black>Playlist</black>
+ </gamepad>
+ </MyMusicFiles>
+ <MyMusicLibrary>
+ <gamepad>
+ <Y>Queue</Y>
+ <black>Playlist</black>
+ </gamepad>
+ </MyMusicLibrary>
+ <FullscreenVideo>
+ <gamepad>
+ <A>Pause</A>
+ <B>Stop</B>
+ <Y>AspectRatio</Y>
+ <black>CodecInfo</black>
+ <white>Info</white>
+ <back>SmallStepBack</back>
+ <start>OSD</start>
+ <leftanalogtrigger>AnalogRewind</leftanalogtrigger>
+ <rightanalogtrigger>AnalogFastForward</rightanalogtrigger>
+ <dpadleft>StepBack</dpadleft>
+ <dpadright>StepForward</dpadright>
+ <dpadup>BigStepForward</dpadup>
+ <dpaddown>BigStepBack</dpaddown>
+ </gamepad>
+ </FullscreenVideo>
+ <FullscreenInfo>
+ <gamepad>
+ <B>Close</B>
+ <start>OSD</start>
+ <black>CodecInfo</black>
+ <white>Close</white>
+ <leftanalogtrigger>AnalogRewind</leftanalogtrigger>
+ <rightanalogtrigger>AnalogFastForward</rightanalogtrigger>
+ </gamepad>
+ </FullscreenInfo>
+ <PlayerControls>
+ <gamepad>
+ <back>Close</back>
+ <start>Close</start>
+ </gamepad>
+ </PlayerControls>
+ <Visualisation>
+ <gamepad>
+ <A>Pause</A>
+ <B>Stop</B>
+ <Y>XBMC.ActivateWindow(VisualisationPresetList)</Y>
+ <black>CodecInfo</black>
+ <white>Info</white>
+ <start>XBMC.ActivateWindow(MusicOSD)</start>
+ <back>LockPreset</back>
+ <leftanalogtrigger>AnalogRewind</leftanalogtrigger>
+ <rightanalogtrigger>AnalogFastForward</rightanalogtrigger>
+ <dpadleft>SkipPrevious</dpadleft>
+ <dpadright>SkipNext</dpadright>
+ <dpadup>NextPreset</dpadup>
+ <dpaddown>PreviousPreset</dpaddown>
+ </gamepad>
+ </Visualisation>
+ <MusicOSD>
+ <gamepad>
+ <back>Close</back>
+ <start>Close</start>
+ <black>CodecInfo</black>
+ <white>Info</white>
+ <leftanalogtrigger>AnalogRewind</leftanalogtrigger>
+ <rightanalogtrigger>AnalogFastForward</rightanalogtrigger>
+ </gamepad>
+ </MusicOSD>
+ <VisualisationSettings>
+ <gamepad>
+ <B>Close</B>
+ <back>Close</back>
+ <start>Close</start>
+ <leftanalogtrigger>AnalogRewind</leftanalogtrigger>
+ <rightanalogtrigger>AnalogFastForward</rightanalogtrigger>
+ </gamepad>
+ </VisualisationSettings>
+ <VisualisationPresetList>
+ <gamepad>
+ <B>Close</B>
+ <back>Close</back>
+ <start>Close</start>
+ <Y>Close</Y>
+ <leftanalogtrigger>AnalogRewind</leftanalogtrigger>
+ <rightanalogtrigger>AnalogFastForward</rightanalogtrigger>
+ </gamepad>
+ </VisualisationPresetList>
+ <SlideShow>
+ <gamepad>
+ <A>Pause</A>
+ <B>Stop</B>
+ <Y>Rotate</Y>
+ <X>ZoomNormal</X>
+ <black>CodecInfo</black>
+ <white>Info</white>
+ <righttrigger>NextPicture</righttrigger>
+ <lefttrigger>PreviousPicture</lefttrigger>
+ <dpadleft>PreviousPicture</dpadleft>
+ <dpadright>NextPicture</dpadright>
+ <dpadup>ZoomIn</dpadup>
+ <dpaddown>ZoomOut</dpaddown>
+ <leftthumbstick>AnalogMove</leftthumbstick>
+ <back>Stop</back>
+ </gamepad>
+ </SlideShow>
+ <ScreenCalibration>
+ <gamepad>
+ <leftthumbstick>AnalogMove</leftthumbstick>
+ <A>NextCalibration</A>
+ <black>ResetCalibration</black>
+ <white>NextResolution</white>
+ <B>PreviousMenu</B>
+ </gamepad>
+ </ScreenCalibration>
+ <GUICalibration>
+ <gamepad>
+ <leftthumbstick>AnalogMove</leftthumbstick>
+ <A>NextCalibration</A>
+ <black>ResetCalibration</black>
+ <B>PreviousMenu</B>
+ </gamepad>
+ </GUICalibration>
+ <SelectDialog>
+ <gamepad>
+ <back>Close</back>
+ </gamepad>
+ </SelectDialog>
+ <VideoOSD>
+ <gamepad>
+ <start>Close</start>
+ <back>PreviousMenu</back>
+ <B>PreviousMenu</B>
+ <black>CodecInfo</black>
+ <white>Info</white>
+ <leftanalogtrigger>AnalogRewind</leftanalogtrigger>
+ <rightanalogtrigger>AnalogFastForward</rightanalogtrigger>
+ </gamepad>
+ </VideoOSD>
+ <VideoMenu>
+ <gamepad>
+ <Y>AspectRatio</Y>
+ <B>Stop</B>
+ <start>OSD</start>
+ <back>PreviousMenu</back>
+ <white>Info</white>
+ <black>CodecInfo</black>
+ <leftanalogtrigger>AnalogRewind</leftanalogtrigger>
+ <rightanalogtrigger>AnalogFastForward</rightanalogtrigger>
+ </gamepad>
+ </VideoMenu>
+ <OSDVideoSettings>
+ <gamepad>
+ <X/>
+ <Y>AspectRatio</Y>
+ <B>Close</B>
+ <back>Close</back>
+ <start>Close</start>
+ <black>CodecInfo</black>
+ <white>Info</white>
+ <leftanalogtrigger>AnalogRewind</leftanalogtrigger>
+ <rightanalogtrigger>AnalogFastForward</rightanalogtrigger>
+ </gamepad>
+ </OSDVideoSettings>
+ <OSDAudioSettings>
+ <gamepad>
+ <X/>
+ <Y>AspectRatio</Y>
+ <B>Close</B>
+ <back>Close</back>
+ <start>Close</start>
+ <black>CodecInfo</black>
+ <white>Info</white>
+ <leftanalogtrigger>AnalogRewind</leftanalogtrigger>
+ <rightanalogtrigger>AnalogFastForward</rightanalogtrigger>
+ </gamepad>
+ </OSDAudioSettings>
+ <VideoBookmarks>
+ <gamepad>
+ <X/>
+ <Y>Delete</Y>
+ <B>Close</B>
+ <back>Close</back>
+ <start>Close</start>
+ <leftanalogtrigger>AnalogRewind</leftanalogtrigger>
+ <rightanalogtrigger>AnalogFastForward</rightanalogtrigger>
+ </gamepad>
+ </VideoBookmarks>
+ <MyVideoLibrary>
+ <gamepad>
+ <black>Delete</black>
+ </gamepad>
+ </MyVideoLibrary>
+ <MyVideoFiles>
+ <gamepad>
+ <Y>Queue</Y>
+ <black>Playlist</black>
+ </gamepad>
+ </MyVideoFiles>
+ <MyVideoPlaylist>
+ <gamepad>
+ <Y>Delete</Y>
+ <black>Playlist</black> <!-- Close playlist -->
+ <back>Playlist</back> <!-- Close playlist -->
+ <B>Playlist</B>
+ </gamepad>
+ </MyVideoPlaylist>
+ <VirtualKeyboard>
+ <gamepad>
+ <start>Enter</start>
+ <B>BackSpace</B>
+ <Y>Shift</Y>
+ <X>Symbols</X>
+ <lefttrigger>CursorLeft</lefttrigger>
+ <righttrigger>CursorRight</righttrigger>
+ </gamepad>
+ </VirtualKeyboard>
+ <ContextMenu>
+ <gamepad>
+ <white>Close</white>
+ <B>Close</B>
+ </gamepad>
+ </ContextMenu>
+ <Scripts>
+ <gamepad>
+ <black>XBMC.ActivateWindow(ScriptsDebugInfo)</black>
+ </gamepad>
+ </Scripts>
+ <ScriptsDebugInfo>
+ <gamepad>
+ <white>Info</white> <!-- clears debug python info -->
+ </gamepad>
+ </ScriptsDebugInfo>
+ <NumericInput>
+ <gamepad>
+ <B>BackSpace</B>
+ <start>Enter</start>
+ <lefttrigger>SkipPrevious</lefttrigger>
+ <righttrigger>SkipNext</righttrigger>
+ </gamepad>
+ </NumericInput>
+ <GamepadInput>
+ <gamepad>
+ <start>Stop</start> <!-- Enter Password -->
+ </gamepad>
+ </GamepadInput>
+ <Weather>
+ <gamepad>
+ <B>PreviousMenu</B>
+ </gamepad>
+ </Weather>
+ <Settings>
+ <gamepad>
+ <B>PreviousMenu</B>
+ </gamepad>
+ </Settings>
+ <MyPicturesSettings>
+ <gamepad>
+ <B>PreviousMenu</B>
+ </gamepad>
+ </MyPicturesSettings>
+ <MyProgramsSettings>
+ <gamepad>
+ <B>PreviousMenu</B>
+ </gamepad>
+ </MyProgramsSettings>
+ <MyWeatherSettings>
+ <gamepad>
+ <B>PreviousMenu</B>
+ </gamepad>
+ </MyWeatherSettings>
+ <MyMusicSettings>
+ <gamepad>
+ <B>PreviousMenu</B>
+ </gamepad>
+ </MyMusicSettings>
+ <SystemSettings>
+ <gamepad>
+ <B>PreviousMenu</B>
+ </gamepad>
+ </SystemSettings>
+ <MyVideosSettings>
+ <gamepad>
+ <B>PreviousMenu</B>
+ </gamepad>
+ </MyVideosSettings>
+ <NetworkSettings>
+ <gamepad>
+ <B>PreviousMenu</B>
+ </gamepad>
+ </NetworkSettings>
+ <AppearanceSettings>
+ <gamepad>
+ <B>PreviousMenu</B>
+ </gamepad>
+ </AppearanceSettings>
+ <Profiles>
+ <gamepad>
+ <B>PreviousMenu</B>
+ </gamepad>
+ </Profiles>
+ <systeminfo>
+ <gamepad>
+ <B>PreviousMenu</B>
+ </gamepad>
+ </systeminfo>
+ <shutdownmenu>
+ <gamepad>
+ <B>PreviousMenu</B>
+ </gamepad>
+ </shutdownmenu>
+ <submenu>
+ <gamepad>
+ <B>PreviousMenu</B>
+ </gamepad>
+ </submenu>
+ <MusicInformation>
+ <gamepad>
+ <B>Close</B>
+ </gamepad>
+ </MusicInformation>
+ <MovieInformation>
+ <gamepad>
+ <B>Close</B>
+ </gamepad>
+ </MovieInformation>
+ <LockSettings>
+ <gamepad>
+ <start>Close</start>
+ <B>PreviousMenu</B>
+ <back>PreviousMenu</back>
+ </gamepad>
+ </LockSettings>
+ <ProfileSettings>
+ <gamepad>
+ <start>Close</start>
+ <B>PreviousMenu</B>
+ <back>PreviousMenu</back>
+ </gamepad>
+ </ProfileSettings>
+ <PictureInfo>
+ <gamepad>
+ <dpadleft>PreviousPicture</dpadleft>
+ <dpadright>NextPicture</dpadright>
+ <black>Close</black>
+ </gamepad>
+ </PictureInfo>
+</keymap>
diff --git a/system/keymaps/joystick.AppleRemote.xml b/system/keymaps/joystick.AppleRemote.xml
new file mode 100644
index 0000000000..b04f2bd598
--- /dev/null
+++ b/system/keymaps/joystick.AppleRemote.xml
@@ -0,0 +1,228 @@
+<!-- This file contains the mapping of keys (gamepad, remote, and keyboard) to actions within XBMC -->
+<!-- The <global> section is a fall through - they will only be used if the button is not -->
+<!-- used in the current window's section. Note that there is only handling -->
+<!-- for a single action per button at this stage. -->
+<!-- For joystick/gamepad configuration under linux/win32, see below as it differs from xbox -->
+<!-- gamepads. -->
+
+<!-- The format is: -->
+<!-- <device> -->
+<!-- <button>action</button> -->
+<!-- </device> -->
+
+<!-- To map keys from other remotes using the RCA protocol, you may add <universalremote> blocks -->
+<!-- In this case, the tags used are <obc#> where # is the original button code (OBC) of the key -->
+<!-- You set it up by adding a <universalremote> block to the window or <global> section: -->
+<!-- <universalremote> -->
+<!-- <obc45>Stop</obc45> -->
+<!-- </universalremote> -->
+<!-- To find out the OBC's of your remote, try enabling the <displayremotecodes> tag in AdvancedSettings.xml -->
+
+<!-- Note that the action can be a built-in function. -->
+<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> -->
+<!-- would automatically go to My Music on the press of the B button. -->
+
+<!-- Joysticks / Gamepads: -->
+<!-- See the sample PS3 controller configuration below for the format. -->
+<!-- -->
+<!-- Joystick Name: -->
+<!-- Do 'cat /proc/bus/input/devices' or see your xbmc log file to find the names of -->
+<!-- detected joysticks. The name used in the configuration should match the detected name. -->
+<!-- -->
+<!-- Button Ids: -->
+<!-- 'id' is the button ID used by SDL. Joystick button ids of connected joysticks appear -->
+<!-- in xbmc.log when they are pressed. Use your log to map custom buttons to actions. -->
+<!-- -->
+<!-- Axis Ids / Analog Controls -->
+<!-- Coming soon. -->
+<keymap>
+ <global>
+ <joystick name="AppleRemote">
+ <!-- plus --> <button id="1">Up</button>
+ <!-- minus --> <button id="2">Down</button>
+ <!-- left --> <button id="3">Left</button>
+ <!-- right --> <button id="4">Right</button>
+ <!-- play/pause --> <button id="5">Select</button>
+ <!-- menu --> <button id="6">PreviousMenu</button>
+ <!-- hold play --> <button id="7">Fullscreen</button>
+ <!-- hold menu --> <button id="8">ContextMenu</button>
+ <!-- old buttons for ATV <2.2, used on OSX -->
+ <!-- hold left --> <button id="9">Left</button>
+ <!-- hold right --> <button id="10">Right</button>
+ <!-- Learned remote buttons (ATV >2.3) -->
+ <!-- Play --> <button id="70">Play</button>
+ <!-- Pause --> <button id="71">Pause</button>
+ <!-- Stop --> <button id="72">Stop</button>
+ <!-- Previous --> <button id="73">SkipPrevious</button>
+ <!-- Next --> <button id="74">SkipNext</button>
+ <!-- Rewind --> <button id="75">Rewind</button>
+ <!-- Forward --> <button id="76">FastForward</button>
+ <!-- Return --> <button id="77">OSD</button>
+ <!-- Enter --> <button id="78">ShowVideoMenu</button>
+ </joystick>
+ </global>
+ <Home>
+ <joystick name="AppleRemote">
+ <button id="6">Fullscreen</button>
+ </joystick>
+ </Home>
+ <MyMusicPlaylist>
+ <joystick name="AppleRemote">
+ <button id="6">Playlist</button>
+ </joystick>
+ </MyMusicPlaylist>
+ <MyMusicPlaylistEditor>
+ <joystick name="AppleRemote">
+ <button id="5">ContextMenu</button>
+ <!-- FIXME? -->
+ <button id="6">Playlist</button>
+ </joystick>
+ </MyMusicPlaylistEditor>
+ <MyMusicFiles>
+ <joystick name="AppleRemote">
+ <button id="6">ParentDir</button>
+ </joystick>
+ </MyMusicFiles>
+ <MyMusicLibrary>
+ <joystick name="AppleRemote">
+ <button id="6">ParentDir</button>
+ </joystick>
+ </MyMusicLibrary>
+ <FullscreenVideo>
+ <joystick name="AppleRemote">
+ <button id="1">VolumeUp</button>
+ <button id="2">VolumeDown</button>
+ <button id="3">StepBack</button>
+ <button id="4">StepForward</button>
+ <button id="5">OSD</button>
+ <button id="6">Fullscreen</button>
+ </joystick>
+ </FullscreenVideo>
+ <FullscreenInfo>
+ <joystick name="AppleRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </FullscreenInfo>
+ <PlayerControls>
+ <joystick name="AppleRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </PlayerControls>
+ <Visualisation>
+ <joystick name="AppleRemote">
+ <button id="1">VolumeUp</button>
+ <button id="2">VolumeDown</button>
+ <button id="3">SkipPrevious</button>
+ <button id="4">SkipNext</button>
+ <button id="5">XBMC.ActivateWindow(MusicOSD)</button>
+ <button id="6">Fullscreen</button>
+ </joystick>
+ </Visualisation>
+ <MusicOSD>
+ <joystick name="AppleRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </MusicOSD>
+ <VisualisationSettings>
+ <joystick name="AppleRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </VisualisationSettings>
+ <VisualisationPresetList>
+ <joystick name="AppleRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </VisualisationPresetList>
+ <SlideShow>
+ <joystick name="AppleRemote">
+ <button id="1">ZoomIn</button>
+ <button id="2">ZoomOut</button>
+ <button id="3">PreviousPicture</button>
+ <button id="4">NextPicture</button>
+ <button id="5">Info</button>
+ <button id="6">Stop</button>
+ </joystick>
+ </SlideShow>
+ <ScreenCalibration>
+ <joystick name="AppleRemote">
+ <button id="5">NextCalibration</button>
+ </joystick>
+ </ScreenCalibration>
+ <SelectDialog>
+ <joystick name="AppleRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </SelectDialog>
+ <VideoOSD>
+ <joystick name="AppleRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </VideoOSD>
+ <VideoMenu>
+ <joystick name="AppleRemote">
+ <button id="5">OSD</button>
+ </joystick>
+ </VideoMenu>
+ <OSDVideoSettings>
+ <joystick name="AppleRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </OSDVideoSettings>
+ <OSDAudioSettings>
+ <joystick name="AppleRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </OSDAudioSettings>
+ <VideoBookmarks>
+ <joystick name="AppleRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </VideoBookmarks>
+ <MyVideoLibrary>
+ <joystick name="AppleRemote">
+ <button id="6">ParentDir</button>
+ </joystick>
+ </MyVideoLibrary>
+ <MyVideoFiles>
+ <joystick name="AppleRemote">
+ <button id="6">ParentDir</button>
+ </joystick>
+ </MyVideoFiles>
+ <MyVideoPlaylist>
+ <joystick name="AppleRemote">
+ <button id="6">Playlist</button>
+ </joystick>
+ </MyVideoPlaylist>
+ <VirtualKeyboard>
+ <joystick name="AppleRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </VirtualKeyboard>
+ <ContextMenu>
+ <joystick name="AppleRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </ContextMenu>
+ <FileStackingDialog>
+ <joystick name="AppleRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </FileStackingDialog>
+ <MusicInformation>
+ <joystick name="AppleRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </MusicInformation>
+ <MovieInformation>
+ <joystick name="AppleRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </MovieInformation>
+ <PictureInfo>
+ <joystick name="AppleRemote">
+ <button id="3">Left</button>
+ <button id="4">Right</button>
+ <button id="6">Close</button>
+ </joystick>
+ </PictureInfo>
+</keymap>
diff --git a/system/keymaps/joystick.Harmony.xml b/system/keymaps/joystick.Harmony.xml
new file mode 100644
index 0000000000..aae66e4cb0
--- /dev/null
+++ b/system/keymaps/joystick.Harmony.xml
@@ -0,0 +1,486 @@
+<!-- This file contains the mapping of keys (gamepad, remote, and keyboard) to actions within XBMC -->
+<!-- The <global> section is a fall through - they will only be used if the button is not -->
+<!-- used in the current window's section. Note that there is only handling -->
+<!-- for a single action per button at this stage. -->
+<!-- For joystick/gamepad configuration under linux/win32, see below as it differs from xbox -->
+<!-- gamepads. -->
+
+<!-- The format is: -->
+<!-- <device> -->
+<!-- <button>action</button> -->
+<!-- </device> -->
+
+<!-- To map keys from other remotes using the RCA protocol, you may add <universalremote> blocks -->
+<!-- In this case, the tags used are <obc#> where # is the original button code (OBC) of the key -->
+<!-- You set it up by adding a <universalremote> block to the window or <global> section: -->
+<!-- <universalremote> -->
+<!-- <obc45>Stop</obc45> -->
+<!-- </universalremote> -->
+<!-- To find out the OBC's of your remote, try enabling the <displayremotecodes> tag in AdvancedSettings.xml -->
+
+<!-- Note that the action can be a built-in function. -->
+<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> -->
+<!-- would automatically go to My Music on the press of the B button. -->
+
+<!-- Joysticks / Gamepads: -->
+<!-- See the sample PS3 controller configuration below for the format. -->
+<!-- -->
+<!-- Joystick Name: -->
+<!-- Do 'cat /proc/bus/input/devices' or see your xbmc log file to find the names of -->
+<!-- detected joysticks. The name used in the configuration should match the detected name. -->
+<!-- -->
+<!-- Button Ids: -->
+<!-- 'id' is the button ID used by SDL. Joystick button ids of connected joysticks appear -->
+<!-- in xbmc.log when they are pressed. Use your log to map custom buttons to actions. -->
+<!-- -->
+<!-- Axis Ids / Analog Controls -->
+<!-- Coming soon. -->
+<keymap>
+ <global>
+ <joystick name="Harmony">
+ <!-- up --> <button id="1">Up</button>
+ <!-- minus --> <button id="2">Down</button>
+ <!-- left --> <button id="3">Left</button>
+ <!-- right --> <button id="4">Right</button>
+ <!-- OK --> <button id="5">Select</button>
+ <!-- menu --> <button id="6">ContextMenu</button>
+ <!-- hold play --> <button id="7">Fullscreen</button>
+ <!-- hold menu --> <button id="8">ContextMenu</button>
+ <!-- hold right --> <button id="9">Right</button>
+ <!-- hold left --> <button id="10">Left</button>
+ <!-- Stop --> <button id="15">Stop</button>
+ <!-- Stop Hold --> <button id="17"/>
+ <!-- Play --> <button id="16">Play</button>
+ <!-- Play Hold --> <button id="18"/>
+ <!-- Replay --> <button id="91">SkipPrevious</button>
+ <!-- Skip --> <button id="92">SkipNext</button>
+ <!-- Record --> <button id="52">Screenshot</button>
+ <!-- Rew --> <button id="41">BigStepBack</button>
+ <!-- Fwd --> <button id="42">BigStepForward</button>
+ <!-- Pause --> <button id="26">Pause</button>
+ <!-- Prev --> <button id="32">ParentDir</button>
+ <!-- Guide --> <button id="65">FullScreen</button>
+ <!-- Info --> <button id="31">Info</button>
+ <!-- Exit --> <button id="51">PreviousMenu</button>
+ <!-- Channel Up --> <button id="71">PageUp</button>
+ <!-- Channel Down --> <button id="72">PageDown</button>
+ <!-- looks like buttons below are duplicates of those above
+ Arrow Up <button id="71"></button>
+ Arrow Down <button id="72"></button>
+ -->
+ <!-- Volume + --> <button id="21">VolumeUp</button>
+ <!-- Volume - --> <button id="22">VolumeDown</button>
+ <!-- 1 --> <button id="11">Number1</button>
+ <!-- 2 --> <button id="12">Number2</button>
+ <!-- 3 --> <button id="13">Number3</button>
+ <!-- 4 --> <button id="14">Number4</button>
+ <!-- 5 --> <button id="23">Number5</button>
+ <!-- 6 --> <button id="24">Number6</button>
+ <!-- 7 --> <button id="33">Number7</button>
+ <!-- 8 --> <button id="34">Number8</button>
+ <!-- 9 --> <button id="43">Number9</button>
+ <!-- 0 --> <button id="44">Number0</button>
+ <!-- * clear --> <button id="45">ParentDir</button>
+ <!-- # enter --> <button id="36">Select</button>
+ <!-- Mute --> <button id="25">Mute</button>
+ <!-- Aspect --> <button id="61">AspectRatio</button>
+ <!-- F1 --> <button id="53">XBMC.ActivateWindow(Music)</button>
+ <!-- F3 --> <button id="55">XBMC.ActivateWindow(videolibrary,tvshowtitles,return)</button>
+ <!-- F2 --> <button id="54">XBMC.ActivateWindow(videolibrary,movietitles,return)</button>
+ <!-- F4 --> <button id="56">XBMC.ActivateWindow(Weather)</button>
+ <!-- F5 --> <button id="93">OSD</button>
+ <!-- F7 --> <button id="95">XBMC.ActivateWindow(settings)</button>
+ <!-- F6 --> <button id="94">XBMC.ActivateWindow(Scripts)</button>
+ <!-- F8 --> <button id="96">XBMC.ActivateWindow(favourites)</button>
+ <!-- F9 --> <button id="73">ShowVideoMenu</button>
+ <!-- F10 --> <button id="74">ShowSubtitles</button>
+ <!-- F11 --> <button id="75">NextSubtitle</button>
+ <!-- F12 --> <button id="76">CodecInfo</button>
+ <!-- F13 --> <button id="63">Playlist</button>
+ <!-- F14 --> <button id="64">AudioNextLanguage</button>
+ <!-- Large Down --> <button id="82">PageDown</button>
+ <!-- Large Up --> <button id="81">PageUp</button>
+ <!-- pwrToggle --> <button id="66">XBMC.ShutDown()</button>
+ <!-- Queue --> <button id="62">Queue</button>
+ <!-- Sleep --> <button id="46">XBMC.SleepSystem()</button>
+ <!-- Red --> <button id="83">XBMC.ActivateWindow(Music)</button>
+ <!-- Green --> <button id="84">XBMC.ActivateWindow(videolibrary,tvshowtitles,return)</button>
+ <!-- Yellow --> <button id="85">xbmc.ActivateWindow(videolibrary,movietitles,return)</button>
+ <!-- Blue --> <button id="86">XBMC.ActivateWindow(Weather)</button>
+ </joystick>
+ </global>
+ <Home>
+ <joystick name="Harmony">
+ <!-- menu --> <button id="6">XBMC.ActivateWindow(PlayerControls)</button>
+ <!-- Info --> <button id="31">XBMC.ActivateWindow(Settings)</button>
+ <!-- Exit --> <button id="51">XBMC.ActivateWindow(ShutdownMenu)</button>
+ <!-- #enter --> <button id="36">XBMC.ActivateWindow(SystemInfo)</button>
+ <!-- 1 --> <button id="11">ToggleFullScreen</button>
+ </joystick>
+ </Home>
+ <MyFiles>
+ <joystick name="Harmony">
+ <!-- 1 --> <button id="11">Highlight</button>
+ <!-- 4 --> <button id="14">Copy</button>
+ <!-- 7 --> <button id="33">Move</button>
+ <!-- * clear --> <button id="45">Delete</button>
+ </joystick>
+ </MyFiles>
+ <MyMusicPlaylist>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">Playlist</button>
+ <!-- * clear --> <button id="45">Delete</button>
+ <!-- Channel Up --> <button id="71">MoveItemUp</button>
+ <!-- Channel Down --> <button id="72">MoveItemDown</button>
+ </joystick>
+ </MyMusicPlaylist>
+ <MyMusicFiles>
+ <joystick name="Harmony">
+ <!-- * clear --> <button id="45">Delete</button>
+ <!-- 1 --> <button id="11">JumpSMS1</button>
+ <!-- 2 --> <button id="12">JumpSMS2</button>
+ <!-- 3 --> <button id="13">JumpSMS3</button>
+ <!-- 4 --> <button id="14">JumpSMS4</button>
+ <!-- 5 --> <button id="23">JumpSMS5</button>
+ <!-- 6 --> <button id="24">JumpSMS6</button>
+ <!-- 7 --> <button id="33">JumpSMS7</button>
+ <!-- 8 --> <button id="34">JumpSMS8</button>
+ <!-- 9 --> <button id="43">JumpSMS9</button>
+ </joystick>
+ </MyMusicFiles>
+ <MyMusicLibrary>
+ <joystick name="Harmony">
+ <!-- 1 --> <button id="11">JumpSMS1</button>
+ <!-- 2 --> <button id="12">JumpSMS2</button>
+ <!-- 3 --> <button id="13">JumpSMS3</button>
+ <!-- 4 --> <button id="14">JumpSMS4</button>
+ <!-- 5 --> <button id="23">JumpSMS5</button>
+ <!-- 6 --> <button id="24">JumpSMS6</button>
+ <!-- 7 --> <button id="33">JumpSMS7</button>
+ <!-- 8 --> <button id="34">JumpSMS8</button>
+ <!-- 9 --> <button id="43">JumpSMS9</button>
+ </joystick>
+ </MyMusicLibrary>
+ <FullscreenVideo>
+ <joystick name="Harmony">
+ <!-- up --> <button id="1">BigStepForward</button>
+ <!-- down --> <button id="2">BigStepBack</button>
+ <!-- left --> <button id="3">StepBack</button>
+ <!-- right --> <button id="4">StepForward</button>
+ <!-- menu --> <button id="6">OSD</button>
+ <!-- Prev --> <button id="32">SmallStepBack</button>
+ <!-- Info --> <button id="31">Info</button>
+ <!-- F7 --> <button id="95">NextSubtitle</button>
+ <!-- F6 --> <button id="94">ShowSubtitles</button>
+ </joystick>
+ </FullscreenVideo>
+ <FullscreenInfo>
+ <joystick name="Harmony">
+ <!-- Info --> <button id="31">Close</button>
+ </joystick>
+ </FullscreenInfo>
+ <PlayerControls>
+ <joystick name="Harmony">
+ <!-- menu --> <button id="6">Close</button>
+ </joystick>
+ </PlayerControls>
+ <Visualisation>
+ <joystick name="Harmony">
+ <!-- up --> <button id="1">IncreaseRating</button>
+ <!-- minus --> <button id="2">DecreaseRating</button>
+ <!-- left --> <button id="3">PreviousPreset</button>
+ <!-- right --> <button id="4">NextPreset</button>
+ <!-- menu --> <button id="6">XBMC.ActivateWindow(MusicOSD)</button>
+ <!-- Prev --> <button id="32">LockPreset</button>
+ <!-- Info --> <button id="31">Info</button>
+ <!-- F8 --> <button id="96">XBMC.ActivateWindow(VisualisationPresetList)</button>
+ <!-- F9 --> <button id="73">XBMC.ActivateWindow(VisualisationSettings)</button>
+ </joystick>
+ </Visualisation>
+ <MusicOSD>
+ <joystick name="Harmony">
+ <!-- menu --> <button id="6">Close</button>
+ <!-- Info --> <button id="31">CodecInfo</button>
+ <!-- Exit --> <button id="51">Close</button>
+ </joystick>
+ </MusicOSD>
+ <VisualisationSettings>
+ <joystick name="Harmony">
+ <!-- menu --> <button id="6">Close</button>
+ <!-- Exit --> <button id="51">Close</button>
+ </joystick>
+ </VisualisationSettings>
+ <VisualisationPresetList>
+ <joystick name="Harmony">
+ <!-- menu --> <button id="6">Close</button>
+ <!-- Exit --> <button id="51">Close</button>
+ </joystick>
+ </VisualisationPresetList>
+ <SlideShow>
+ <joystick name="Harmony">
+ <!-- 1 --> <button id="11">ZoomLevel1</button>
+ <!-- 2 --> <button id="12">ZoomLevel2</button>
+ <!-- 3 --> <button id="13">ZoomLevel3</button>
+ <!-- 4 --> <button id="14">ZoomLevel4</button>
+ <!-- 5 --> <button id="23">ZoomLevel5</button>
+ <!-- 6 --> <button id="24">ZoomLevel6</button>
+ <!-- 7 --> <button id="33">ZoomLevel7</button>
+ <!-- 8 --> <button id="34">ZoomLevel8</button>
+ <!-- 9 --> <button id="43">ZoomLevel9</button>
+ <!-- 0 --> <button id="44">ZoomNormal</button>
+ <!-- Skip --> <button id="92">NextPicture</button>
+ <!-- Replay --> <button id="91">PreviousPicture</button>
+ <!-- Info --> <button id="31">Info</button>
+ <!-- OK --> <button id="5">Rotate</button>
+ </joystick>
+ </SlideShow>
+ <ScreenCalibration>
+ <joystick name="Harmony">
+ <!-- OK --> <button id="5">NextCalibration</button>
+ <!-- 0 --> <button id="44">ResetCalibration</button>
+ <!-- # enter --> <button id="36">NextCalibration</button>
+ <!-- Guide --> <button id="65">NextResolution</button>
+ </joystick>
+ </ScreenCalibration>
+ <GUICalibration>
+ <joystick name="Harmony">
+ <!-- OK --> <button id="5">NextCalibration</button>
+ <!-- 0 --> <button id="44">ResetCalibration</button>
+ <!-- # enter --> <button id="36">NextCalibration</button>
+ </joystick>
+ </GUICalibration>
+ <SelectDialog>
+ <joystick name="Harmony">
+ <!-- Exit --> <button id="51">Close</button>
+ <!-- Prev --> <button id="32">Close</button>
+ </joystick>
+ </SelectDialog>
+ <VideoOSD>
+ <joystick name="Harmony">
+ <!-- menu --> <button id="6">Close</button>
+ <!-- Exit --> <button id="51">Close</button>
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </VideoOSD>
+ <VideoMenu>
+ <joystick name="Harmony">
+ <!-- menu --> <button id="6">OSD</button>
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ <!-- Info --> <button id="31">Info</button>
+ </joystick>
+ </VideoMenu>
+ <OSDVideoSettings>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">Close</button>
+ <!-- menu --> <button id="6">Close</button>
+ </joystick>
+ </OSDVideoSettings>
+ <OSDAudioSettings>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">Close</button>
+ <!-- menu --> <button id="6">Close</button>
+ <!-- Exit --> <button id="51">Close</button>
+ </joystick>
+ </OSDAudioSettings>
+ <VideoBookmarks>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">Close</button>
+ <!-- menu --> <button id="6">Close</button>
+ <!-- Exit --> <button id="51">Close</button>
+ <!-- * clear --> <button id="45">Delete</button>
+ </joystick>
+ </VideoBookmarks>
+ <MyVideoLibrary>
+ <joystick name="Harmony">
+ <!-- * clear --> <button id="45">Delete</button>
+ <!-- # enter --> <button id="36">ToggleWatched</button>
+ <!-- 1 --> <button id="11">JumpSMS1</button>
+ <!-- 2 --> <button id="12">JumpSMS2</button>
+ <!-- 3 --> <button id="13">JumpSMS3</button>
+ <!-- 4 --> <button id="14">JumpSMS4</button>
+ <!-- 5 --> <button id="23">JumpSMS5</button>
+ <!-- 6 --> <button id="24">JumpSMS6</button>
+ <!-- 7 --> <button id="33">JumpSMS7</button>
+ <!-- 8 --> <button id="34">JumpSMS8</button>
+ <!-- 9 --> <button id="43">JumpSMS9</button>
+ </joystick>
+ </MyVideoLibrary>
+ <MyVideoFiles>
+ <joystick name="Harmony">
+ <!-- * clear --> <button id="45">Delete</button>
+ <!-- 1 --> <button id="11">JumpSMS1</button>
+ <!-- 2 --> <button id="12">JumpSMS2</button>
+ <!-- 3 --> <button id="13">JumpSMS3</button>
+ <!-- 4 --> <button id="14">JumpSMS4</button>
+ <!-- 5 --> <button id="23">JumpSMS5</button>
+ <!-- 6 --> <button id="24">JumpSMS6</button>
+ <!-- 7 --> <button id="33">JumpSMS7</button>
+ <!-- 8 --> <button id="34">JumpSMS8</button>
+ <!-- 9 --> <button id="43">JumpSMS9</button>
+ </joystick>
+ </MyVideoFiles>
+ <MyVideoPlaylist>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">Playlist</button> <!-- Close playlist -->
+ <!-- * clear --> <button id="45">Delete</button>
+ <!-- Channel Up --> <button id="71">MoveItemUp</button>
+ <!-- Channel Down --> <button id="72">MoveItemDown</button>
+ </joystick>
+ </MyVideoPlaylist>
+ <VirtualKeyboard>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">BackSpace</button>
+ <!-- * clear --> <button id="45">Shift</button>
+ <!-- # enter --> <button id="36">Symbols</button>
+ <!-- 1 --> <button id="11">Number1</button>
+ <!-- 2 --> <button id="12">Number2</button>
+ <!-- 3 --> <button id="13">Number3</button>
+ <!-- 4 --> <button id="14">Number4</button>
+ <!-- 5 --> <button id="23">Number5</button>
+ <!-- 6 --> <button id="24">Number6</button>
+ <!-- 7 --> <button id="33">Number7</button>
+ <!-- 8 --> <button id="34">Number8</button>
+ <!-- 9 --> <button id="43">Number9</button>
+ <!-- 0 --> <button id="44">Number0</button>
+ <!-- Rew --> <button id="41">CursorLeft</button>
+ <!-- Fwd --> <button id="42">CursorRight</button>
+ </joystick>
+ </VirtualKeyboard>
+ <ContextMenu>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">Close</button>
+ </joystick>
+ </ContextMenu>
+ <FileStackingDialog>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">Close</button>
+ </joystick>
+ </FileStackingDialog>
+ <Scripts>
+ <joystick name="Harmony">
+ <!-- Info --> <button id="31">XBMC.ActivateWindow(ScriptsDebugInfo)</button>
+ </joystick>
+ </Scripts>
+ <ScriptsDebugInfo>
+ <joystick name="Harmony">
+ <!-- Info --> <button id="31">Info</button> <!-- clears debug python info -->
+ </joystick>
+ </ScriptsDebugInfo>
+ <NumericInput>
+ <joystick name="Harmony">
+ <!-- 1 --> <button id="11">Number1</button>
+ <!-- 2 --> <button id="12">Number2</button>
+ <!-- 3 --> <button id="13">Number3</button>
+ <!-- 4 --> <button id="14">Number4</button>
+ <!-- 5 --> <button id="23">Number5</button>
+ <!-- 6 --> <button id="24">Number6</button>
+ <!-- 7 --> <button id="33">Number7</button>
+ <!-- 8 --> <button id="34">Number8</button>
+ <!-- 9 --> <button id="43">Number9</button>
+ <!-- 0 --> <button id="44">Number0</button>
+ <!-- Prev --> <button id="32">BackSpace</button>
+ </joystick>
+ </NumericInput>
+ <Weather>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </Weather>
+ <Settings>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </Settings>
+ <MyPicturesSettings>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </MyPicturesSettings>
+ <MyProgramsSettings>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </MyProgramsSettings>
+ <MyWeatherSettings>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </MyWeatherSettings>
+ <MyMusicSettings>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </MyMusicSettings>
+ <SystemSettings>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </SystemSettings>
+ <MyVideosSettings>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </MyVideosSettings>
+ <NetworkSettings>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </NetworkSettings>
+ <AppearanceSettings>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </AppearanceSettings>
+ <Profiles>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </Profiles>
+ <systeminfo>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </systeminfo>
+ <shutdownmenu>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </shutdownmenu>
+ <submenu>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </submenu>
+ <MusicInformation>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">Close</button>
+ <!-- menu --> <button id="6">Close</button>
+ </joystick>
+ </MusicInformation>
+ <MovieInformation>
+ <joystick name="Harmony">
+ <!-- Prev --> <button id="32">Close</button>
+ <!-- menu --> <button id="6">Close</button>
+ </joystick>
+ </MovieInformation>
+ <LockSettings>
+ <joystick name="Harmony">
+ <!-- menu --> <button id="6">Close</button>
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </LockSettings>
+ <ProfileSettings>
+ <joystick name="Harmony">
+ <!-- menu --> <button id="6">Close</button>
+ <!-- Prev --> <button id="32">PreviousMenu</button>
+ </joystick>
+ </ProfileSettings>
+ <PictureInfo>
+ <joystick name="Harmony">
+ <!-- Replay --> <button id="91">PreviousPicture</button>
+ <!-- Skip --> <button id="92">NextPicture</button>
+ <!-- Info --> <button id="31">Close</button>
+ <!-- Prev --> <button id="32">Close</button>
+ </joystick>
+ </PictureInfo>
+</keymap>
diff --git a/system/keymaps/joystick.Microsoft.Xbox.Controller.S.xml b/system/keymaps/joystick.Microsoft.Xbox.Controller.S.xml
new file mode 100644
index 0000000000..c848efc69f
--- /dev/null
+++ b/system/keymaps/joystick.Microsoft.Xbox.Controller.S.xml
@@ -0,0 +1,487 @@
+<!-- This file contains the mapping of keys (gamepad, remote, and keyboard) to actions within XBMC -->
+<!-- The <global> section is a fall through - they will only be used if the button is not -->
+<!-- used in the current window's section. Note that there is only handling -->
+<!-- for a single action per button at this stage. -->
+<!-- For joystick/gamepad configuration under linux/win32, see below as it differs from xbox -->
+<!-- gamepads. -->
+
+<!-- The format is: -->
+<!-- <device> -->
+<!-- <button>action</button> -->
+<!-- </device> -->
+
+<!-- To map keys from other remotes using the RCA protocol, you may add <universalremote> blocks -->
+<!-- In this case, the tags used are <obc#> where # is the original button code (OBC) of the key -->
+<!-- You set it up by adding a <universalremote> block to the window or <global> section: -->
+<!-- <universalremote> -->
+<!-- <obc45>Stop</obc45> -->
+<!-- </universalremote> -->
+<!-- To find out the OBC's of your remote, try enabling the <displayremotecodes> tag in AdvancedSettings.xml -->
+
+<!-- Note that the action can be a built-in function. -->
+<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> -->
+<!-- would automatically go to My Music on the press of the B button. -->
+
+<!-- Joysticks / Gamepads: -->
+<!-- See the sample PS3 controller configuration below for the format. -->
+<!-- -->
+<!-- Joystick Name: -->
+<!-- Do 'cat /proc/bus/input/devices' or see your xbmc log file to find the names of -->
+<!-- detected joysticks. The name used in the configuration should match the detected name. -->
+<!-- -->
+<!-- Button Ids: -->
+<!-- 'id' is the button ID used by SDL. Joystick button ids of connected joysticks appear -->
+<!-- in xbmc.log when they are pressed. Use your log to map custom buttons to actions. -->
+<!-- -->
+<!-- Axis Ids / Analog Controls -->
+<!-- Coming soon. -->
+<keymap>
+ <global>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="1">Select</button>
+ <button id="2">ParentDir</button>
+ <button id="3"/>
+ <button id="4">FullScreen</button>
+ <button id="5">Queue</button>
+ <button id="6">ContextMenu</button>
+ <button id="7"/>
+ <button id="8"/>
+ <button id="9">XBMC.ActivateWindow(PlayerControls)</button>
+ <button id="10"/>
+ <button id="11">Screenshot</button>
+ <button id="12">XBMC.ActivateWindow(ShutdownMenu)</button>
+ <button id="13">Up</button>
+ <button id="14">Right</button>
+ <button id="15">Down</button>
+ <button id="16">Left</button>
+ <button id="17">PreviousMenu</button>
+ <axis limit="-1" id="5">VolumeDown</axis>
+ <axis limit="+1" id="5">VolumeUp</axis>
+ <axis limit="-1" id="4">AnalogSeekBack</axis>
+ <axis limit="+1" id="4">AnalogSeekForward</axis>
+ <axis limit="0" id="3">ScrollUp</axis>
+ <axis limit="0" id="6">ScrollDown</axis>
+ </joystick>
+ </global>
+ <Home>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="3">XBMC.Skin.ToggleSetting(HomeViewToggle)</button>
+ </joystick>
+ </Home>
+ <MyFiles>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="5">Highlight</button>
+ </joystick>
+ </MyFiles>
+ <MyMusicPlaylist>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">Playlist</button>
+ <button id="3">Playlist</button>
+ <button id="17">Playlist</button>
+ <button id="5">Delete</button>
+ </joystick>
+ </MyMusicPlaylist>
+ <MyMusicFiles>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="3">Playlist</button>
+ <button id="5">Queue</button>
+ </joystick>
+ </MyMusicFiles>
+ <MyMusicLibrary>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="3">Playlist</button>
+ <button id="5">Queue</button>
+ </joystick>
+ </MyMusicLibrary>
+ <FullscreenVideo>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="1">Pause</button>
+ <button id="2">Stop</button>
+ <button id="3">CodecInfo</button>
+ <button id="5">AspectRatio</button>
+ <button id="6">Info</button>
+ <button id="9">OSD</button>
+ <button id="13">BigStepForward</button>
+ <button id="14">StepForward</button>
+ <button id="15">BigStepBack</button>
+ <button id="16">StepBack</button>
+ <button id="17">SmallStepBack</button>
+ <axis limit="0" id="3">AnalogRewind</axis>
+ <axis limit="0" id="6">AnalogFastForward</axis>
+ </joystick>
+ </FullscreenVideo>
+ <FullscreenInfo>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">Close</button>
+ <button id="3">CodecInfo</button>
+ <button id="6">Close</button>
+ <button id="9">OSD</button>
+ <axis limit="0" id="3">AnalogRewind</axis>
+ <axis limit="0" id="6">AnalogFastForward</axis>
+ </joystick>
+ </FullscreenInfo>
+ <PlayerControls>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="9">Close</button>
+ <button id="17">Close</button>
+ </joystick>
+ </PlayerControls>
+ <Visualisation>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="1">Pause</button>
+ <button id="2">Stop</button>
+ <button id="3">CodecInfo</button>
+ <button id="5">XBMC.ActivateWindow(VisualisationPresetList)</button>
+ <button id="6">Info</button>
+ <button id="9">XBMC.ActivateWindow(MusicOSD)</button>
+ <button id="13">NextPreset</button>
+ <button id="14">SkipNext</button>
+ <button id="15">PreviousPreset</button>
+ <button id="16">SkipPrevious</button>
+ <axis limit="0" id="3">AnalogRewind</axis>
+ <axis limit="0" id="6">AnalogFastForward</axis>
+ </joystick>
+ </Visualisation>
+ <MusicOSD>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="17">Close</button>
+ <button id="19">Close</button>
+ <button id="3">CodecInfo</button>
+ <button id="6">Info</button>
+ </joystick>
+ </MusicOSD>
+ <VisualisationSettings>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">Close</button>
+ <button id="3">Close</button>
+ <button id="9">Close</button>
+ </joystick>
+ </VisualisationSettings>
+ <VisualisationPresetList>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">Close</button>
+ <button id="3">Close</button>
+ <button id="5">Close</button>
+ <button id="9">Close</button>
+ </joystick>
+ </VisualisationPresetList>
+ <SlideShow>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="1">Pause</button>
+ <button id="2">Stop</button>
+ <button id="3">CodecInfo</button>
+ <button id="4">ZoomNormal</button>
+ <button id="5">Rotate</button>
+ <button id="6">Info</button>
+ <button id="13">ZoomIn</button>
+ <button id="14">NextPicture</button>
+ <button id="15">ZoomOut</button>
+ <button id="16">PreviousPicture</button>
+ <button id="17">Stop</button>
+ </joystick>
+ </SlideShow>
+ <ScreenCalibration>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="1">NextCalibration</button>
+ <button id="3">ResetCalibration</button>
+ <button id="6">NextResolution</button>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </ScreenCalibration>
+ <GUICalibration>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="1">NextCalibration</button>
+ <button id="3">ResetCalibration</button>
+ <button id="6">NextResolution</button>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </GUICalibration>
+ <SelectDialog>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="17">Close</button>
+ </joystick>
+ </SelectDialog>
+ <VideoOSD>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="9">Close</button>
+ <button id="17">PreviousMenu</button>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </VideoOSD>
+ <VideoMenu>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="5">AspectRatio</button>
+ <button id="2">Stop</button>
+ <button id="9">OSD</button>
+ <button id="17">PreviousMenu</button>
+ <button id="6">Info</button>
+ <button id="3">CodecInfo</button>
+ </joystick>
+ </VideoMenu>
+ <OSDVideoSettings>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="4"/>
+ <button id="5">AspectRatio</button>
+ <button id="2">Close</button>
+ <button id="17">Close</button>
+ <button id="19">Close</button>
+ </joystick>
+ </OSDVideoSettings>
+ <OSDAudioSettings>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="4"/>
+ <button id="5">AspectRatio</button>
+ <button id="2">Close</button>
+ <button id="17">Close</button>
+ <button id="19">Close</button>
+ </joystick>
+ </OSDAudioSettings>
+ <VideoBookmarks>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="4"/>
+ <button id="5">Delete</button>
+ <button id="2">Close</button>
+ <button id="17">Close</button>
+ <button id="19">Close</button>
+ </joystick>
+ </VideoBookmarks>
+ <MyVideoLibrary>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="3">Delete</button>
+ </joystick>
+ </MyVideoLibrary>
+ <MyVideoFiles>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="5">Queue</button>
+ <button id="3">Playlist</button>
+ </joystick>
+ </MyVideoFiles>
+ <MyVideoPlaylist>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="5">Delete</button>
+ <button id="3">Playlist</button>
+ <button id="17">Playlist</button>
+ <button id="2">Playlist</button>
+ </joystick>
+ </MyVideoPlaylist>
+ <VirtualKeyboard>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="9">Enter</button>
+ <button id="2">BackSpace</button>
+ <button id="5">Shift</button>
+ <button id="4">Symbols</button>
+ </joystick>
+ </VirtualKeyboard>
+ <ContextMenu>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="6">Close</button>
+ <button id="2">Close</button>
+ </joystick>
+ </ContextMenu>
+ <Scripts>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="3">XBMC.ActivateWindow(ScriptsDebugInfo)</button>
+ </joystick>
+ </Scripts>
+ <NumericInput>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">BackSpace</button>
+ <button id="9">Enter</button>
+ </joystick>
+ </NumericInput>
+ <GamepadInput>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="9">Stop</button> <!-- Enter Password -->
+ </joystick>
+ </GamepadInput>
+ <Weather>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </Weather>
+ <Settings>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </Settings>
+ <MyPicturesSettings>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </MyPicturesSettings>
+ <MyProgramsSettings>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </MyProgramsSettings>
+ <MyWeatherSettings>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </MyWeatherSettings>
+ <MyMusicSettings>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </MyMusicSettings>
+ <SystemSettings>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </SystemSettings>
+ <MyVideosSettings>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </MyVideosSettings>
+ <NetworkSettings>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </NetworkSettings>
+ <AppearanceSettings>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </AppearanceSettings>
+ <Profiles>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </Profiles>
+ <systeminfo>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </systeminfo>
+ <shutdownmenu>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </shutdownmenu>
+ <submenu>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">PreviousMenu</button>
+ </joystick>
+ </submenu>
+ <MusicInformation>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">Close</button>
+ </joystick>
+ </MusicInformation>
+ <MovieInformation>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="2">Close</button>
+ </joystick>
+ </MovieInformation>
+ <LockSettings>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="9">Close</button>
+ <button id="2">PreviousMenu</button>
+ <button id="17">PreviousMenu</button>
+ </joystick>
+ </LockSettings>
+ <ProfileSettings>
+ <joystick name="Microsoft Xbox Controller S">
+ <altname>Mad Catz MicroCON</altname>
+ <altname>Logitech Xbox Cordless Controller</altname>
+ <button id="9">Close</button>
+ <button id="2">PreviousMenu</button>
+ <button id="17">PreviousMenu</button>
+ </joystick>
+ </ProfileSettings>
+</keymap>
diff --git a/system/keymaps/joystick.Sony.PLAYSTATION(R)3.Controller.xml b/system/keymaps/joystick.Sony.PLAYSTATION(R)3.Controller.xml
new file mode 100644
index 0000000000..4cbb441b9f
--- /dev/null
+++ b/system/keymaps/joystick.Sony.PLAYSTATION(R)3.Controller.xml
@@ -0,0 +1,63 @@
+<!-- This file contains the mapping of keys (gamepad, remote, and keyboard) to actions within XBMC -->
+<!-- The <global> section is a fall through - they will only be used if the button is not -->
+<!-- used in the current window's section. Note that there is only handling -->
+<!-- for a single action per button at this stage. -->
+<!-- For joystick/gamepad configuration under linux/win32, see below as it differs from xbox -->
+<!-- gamepads. -->
+
+<!-- The format is: -->
+<!-- <device> -->
+<!-- <button>action</button> -->
+<!-- </device> -->
+
+<!-- To map keys from other remotes using the RCA protocol, you may add <universalremote> blocks -->
+<!-- In this case, the tags used are <obc#> where # is the original button code (OBC) of the key -->
+<!-- You set it up by adding a <universalremote> block to the window or <global> section: -->
+<!-- <universalremote> -->
+<!-- <obc45>Stop</obc45> -->
+<!-- </universalremote> -->
+<!-- To find out the OBC's of your remote, try enabling the <displayremotecodes> tag in AdvancedSettings.xml -->
+
+<!-- Note that the action can be a built-in function. -->
+<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> -->
+<!-- would automatically go to My Music on the press of the B button. -->
+
+<!-- Joysticks / Gamepads: -->
+<!-- See the sample PS3 controller configuration below for the format. -->
+<!-- -->
+<!-- Joystick Name: -->
+<!-- Do 'cat /proc/bus/input/devices' or see your xbmc log file to find the names of -->
+<!-- detected joysticks. The name used in the configuration should match the detected name. -->
+<!-- -->
+<!-- Button Ids: -->
+<!-- 'id' is the button ID used by SDL. Joystick button ids of connected joysticks appear -->
+<!-- in xbmc.log when they are pressed. Use your log to map custom buttons to actions. -->
+<!-- -->
+<!-- Axis Ids / Analog Controls -->
+<!-- Coming soon. -->
+<keymap>
+ <global>
+ <joystick name="Sony PLAYSTATION(R)3 Controller">
+ <altname>PS3 Controller</altname>
+ <altname>Sony Computer Entertainment Wireless Controller</altname>
+ <button id="15">Select</button>
+ <button id="14">ParentDir</button>
+ <button id="16">FullScreen</button>
+ <button id="13">Queue</button>
+ <button id="11">PreviousMenu</button>
+ <button id="8">Left</button>
+ <button id="6">Right</button>
+ <button id="5">Up</button>
+ <button id="7">Down</button>
+ <button id="2">Screenshot</button>
+ <button id="3">XBMC.ActivateWindow(ShutdownMenu)</button>
+ <button id="4">XBMC.ActivateWindow(PlayerControls)</button>
+ <axis limit="+1" id="4">VolumeDown</axis>
+ <axis limit="-1" id="4">VolumeUp</axis>
+ <axis limit="+1" id="1">AnalogSeekForward</axis>
+ <axis limit="-1" id="1">AnalogSeekBack</axis>
+ <axis limit="+1" id="13">ScrollUp</axis>
+ <axis limit="+1" id="14">ScrollDown</axis>
+ </joystick>
+ </global>
+</keymap>
diff --git a/system/keymaps/joystick.WiiRemote.xml b/system/keymaps/joystick.WiiRemote.xml
new file mode 100644
index 0000000000..74a545b604
--- /dev/null
+++ b/system/keymaps/joystick.WiiRemote.xml
@@ -0,0 +1,271 @@
+<!-- This file contains the mapping of keys (gamepad, remote, and keyboard) to actions within XBMC -->
+<!-- The <global> section is a fall through - they will only be used if the button is not -->
+<!-- used in the current window's section. Note that there is only handling -->
+<!-- for a single action per button at this stage. -->
+<!-- For joystick/gamepad configuration under linux/win32, see below as it differs from xbox -->
+<!-- gamepads. -->
+
+<!-- The format is: -->
+<!-- <device> -->
+<!-- <button>action</button> -->
+<!-- </device> -->
+
+<!-- To map keys from other remotes using the RCA protocol, you may add <universalremote> blocks -->
+<!-- In this case, the tags used are <obc#> where # is the original button code (OBC) of the key -->
+<!-- You set it up by adding a <universalremote> block to the window or <global> section: -->
+<!-- <universalremote> -->
+<!-- <obc45>Stop</obc45> -->
+<!-- </universalremote> -->
+<!-- To find out the OBC's of your remote, try enabling the <displayremotecodes> tag in AdvancedSettings.xml -->
+
+<!-- Note that the action can be a built-in function. -->
+<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> -->
+<!-- would automatically go to My Music on the press of the B button. -->
+
+<!-- Joysticks / Gamepads: -->
+<!-- See the sample PS3 controller configuration below for the format. -->
+<!-- -->
+<!-- Joystick Name: -->
+<!-- Do 'cat /proc/bus/input/devices' or see your xbmc log file to find the names of -->
+<!-- detected joysticks. The name used in the configuration should match the detected name. -->
+<!-- -->
+<!-- Button Ids: -->
+<!-- 'id' is the button ID used by SDL. Joystick button ids of connected joysticks appear -->
+<!-- in xbmc.log when they are pressed. Use your log to map custom buttons to actions. -->
+<!-- -->
+<!-- Axis Ids / Analog Controls -->
+<!-- Coming soon. -->
+<keymap>
+ <global>
+ <joystick name="WiiRemote">
+ <button id="1">Up</button>
+ <button id="2">Down</button>
+ <button id="3">Left</button>
+ <button id="4">Right</button>
+ <button id="5">Select</button>
+ <button id="6">PreviousMenu</button>
+ <button id="7">VolumeDown</button>
+ <button id="8">XBMC.ActivateWindow(Home)</button>
+ <button id="9">VolumeUp</button>
+ <button id="10">ContextMenu</button>
+ <button id="11">XBMC.ActivateWindow(PlayerControls)</button>
+ </joystick>
+ </global>
+ <Home>
+ <joystick name="WiiRemote">
+ <button id="8">Fullscreen</button>
+ <button id="10">XBMC.ActivateWindow(Favourites)</button>
+ <button id="11">XBMC.ActivateWindow(ShutdownMenu)</button>
+ </joystick>
+ </Home>
+ <MyFiles>
+ <joystick name="WiiRemote">
+ <button id="7">Move</button>
+ <button id="9">Copy</button>
+ <button id="11">Highlight</button>
+ </joystick>
+ </MyFiles>
+ <MyMusicPlaylist>
+ <joystick name="WiiRemote">
+ <button id="6">Playlist</button>
+ <button id="7">MoveItemUp</button>
+ <button id="9">MoveItemDown</button>
+ <button id="11">Delete</button>
+ </joystick>
+ </MyMusicPlaylist>
+ <MyMusicPlaylistEditor>
+ <joystick name="WiiRemote">
+ <button id="6">Playlist</button>
+ <button id="7">MoveItemUp</button>
+ <button id="9">MoveItemDown</button>
+ <button id="11">Delete</button>
+ </joystick>
+ </MyMusicPlaylistEditor>
+ <MyMusicFiles>
+ <joystick name="WiiRemote">
+ <button id="6">ParentDir</button>
+ <button id="11">Playlist</button>
+ </joystick>
+ </MyMusicFiles>
+ <MyMusicLibrary>
+ <joystick name="WiiRemote">
+ <button id="6">ParentDir</button>
+ <button id="11">Playlist</button>
+ </joystick>
+ </MyMusicLibrary>
+ <FullscreenVideo>
+ <joystick name="WiiRemote">
+ <button id="1">Pause</button>
+ <button id="2">Stop</button>
+ <button id="3">StepBack</button>
+ <button id="4">StepForward</button>
+ <button id="5">OSD</button>
+ <button id="6">Info</button>
+ <button id="10">CodecInfo</button>
+ <button id="11">AspectRatio</button>
+ </joystick>
+ </FullscreenVideo>
+ <FullscreenInfo>
+ <joystick name="WiiRemote">
+ <button id="5">CodecInfo</button>
+ <button id="6">Close</button>
+ </joystick>
+ </FullscreenInfo>
+ <PlayerControls>
+ <joystick name="WiiRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </PlayerControls>
+ <Visualisation>
+ <joystick name="WiiRemote">
+ <button id="1">Pause</button>
+ <button id="2">Stop</button>
+ <button id="3">SkipNext</button>
+ <button id="4">SkipPrevious</button>
+ <button id="5">XBMC.ActivateWindow(MusicOSD)</button>
+ <button id="6">Info</button>
+ <button id="10">IncreaseRating</button>
+ <button id="11">DecreaseRating</button>
+ </joystick>
+ </Visualisation>
+ <MusicOSD>
+ <joystick name="WiiRemote">
+ <button id="6">Close</button>
+ <button id="10">CodecInfo</button>
+ <button id="11">Info</button>
+ </joystick>
+ </MusicOSD>
+ <VisualisationSettings>
+ <joystick name="WiiRemote">
+ <button id="6">Close</button>
+ <button id="10">XBMC.ActivateWindow(VisualisationPresetList)</button>
+ <button id="11">XBMC.ActivateWindow(MusicPlaylist)</button>
+ </joystick>
+ </VisualisationSettings>
+ <VisualisationPresetList>
+ <joystick name="WiiRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </VisualisationPresetList>
+ <SlideShow>
+ <joystick name="WiiRemote">
+ <button id="1">Pause</button>
+ <button id="2">Stop</button>
+ <button id="3">PreviousPicture</button>
+ <button id="4">NextPicture</button>
+ <button id="5">CodecInfo</button>
+ <button id="6">Info</button>
+ <button id="10">ZoomIn</button>
+ <button id="11">ZoomOut</button>
+ </joystick>
+ </SlideShow>
+ <ScreenCalibration>
+ <joystick name="WiiRemote">
+ <button id="5">NextCalibration</button>
+ <button id="10">NextResolution</button>
+ <button id="11">ResetResolution</button>
+ </joystick>
+ </ScreenCalibration>
+ <SelectDialog>
+ <joystick name="WiiRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </SelectDialog>
+ <VideoOSD>
+ <joystick name="WiiRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </VideoOSD>
+ <VideoMenu>
+ <joystick name="WiiRemote">
+ <button id="5">OSD</button>
+ <button id="10">Info</button>
+ <button id="11">AspectRatio</button>
+ </joystick>
+ </VideoMenu>
+ <OSDVideoSettings>
+ <joystick name="WiiRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </OSDVideoSettings>
+ <OSDAudioSettings>
+ <joystick name="WiiRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </OSDAudioSettings>
+ <VideoBookmarks>
+ <joystick name="WiiRemote">
+ <button id="6">Close</button>
+ <button id="11">Delete</button>
+ </joystick>
+ </VideoBookmarks>
+ <MyVideoLibrary>
+ <joystick name="WiiRemote">
+ <button id="6">ParentDir</button>
+ <button id="11">Playlist</button>
+ </joystick>
+ </MyVideoLibrary>
+ <MyVideoFiles>
+ <joystick name="WiiRemote">
+ <button id="6">ParentDir</button>
+ <button id="11">Playlist</button>
+ </joystick>
+ </MyVideoFiles>
+ <MyVideoPlaylist>
+ <joystick name="WiiRemote">
+ <button id="6">Playlist</button>
+ <button id="7">MoveItemDown</button>
+ <button id="9">MoveItemUp</button>
+ <button id="11">Delete</button>
+ </joystick>
+ </MyVideoPlaylist>
+ <VirtualKeyboard>
+ <joystick name="WiiRemote">
+ <button id="6">Shift</button>
+ <button id="7">CursorLeft</button>
+ <button id="9">CursorRight</button>
+ <button id="10">Symbols</button>
+ <button id="11">BackSpace</button>
+ </joystick>
+ </VirtualKeyboard>
+ <ContextMenu>
+ <joystick name="WiiRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </ContextMenu>
+ <Scripts>
+ <joystick name="WiiRemote">
+ <button id="11">XBMC.ActivateWindow(ScriptsDebugInfo)</button>
+ </joystick>
+ </Scripts>
+ <ScriptsDebugInfo>
+ <joystick name="WiiRemote">
+ <button id="11">Info</button>
+ </joystick>
+ </ScriptsDebugInfo>
+ <NumericInput>
+ <joystick name="WiiRemote">
+ <button id="7">SkipPrevious</button>
+ <button id="9">SkipNext</button>
+ <button id="10">Enter</button>
+ <button id="11">BackSpace</button>
+ </joystick>
+ </NumericInput>
+ <MusicInformation>
+ <joystick name="WiiRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </MusicInformation>
+ <MovieInformation>
+ <joystick name="WiiRemote">
+ <button id="6">Close</button>
+ </joystick>
+ </MovieInformation>
+ <PictureInfo>
+ <joystick name="WiiRemote">
+ <button id="3">PreviousPicture</button>
+ <button id="4">NextPicture</button>
+ <button id="6">Close</button>
+ </joystick>
+ </PictureInfo>
+</keymap>
diff --git a/system/keymaps/keyboard.xml b/system/keymaps/keyboard.xml
new file mode 100644
index 0000000000..e73aa0030c
--- /dev/null
+++ b/system/keymaps/keyboard.xml
@@ -0,0 +1,497 @@
+<!-- This file contains the mapping of keys (gamepad, remote, and keyboard) to actions within XBMC -->
+<!-- The <global> section is a fall through - they will only be used if the button is not -->
+<!-- used in the current window's section. Note that there is only handling -->
+<!-- for a single action per button at this stage. -->
+<!-- For joystick/gamepad configuration under linux/win32, see below as it differs from xbox -->
+<!-- gamepads. -->
+
+<!-- The format is: -->
+<!-- <device> -->
+<!-- <button>action</button> -->
+<!-- </device> -->
+
+<!-- To map keys from other remotes using the RCA protocol, you may add <universalremote> blocks -->
+<!-- In this case, the tags used are <obc#> where # is the original button code (OBC) of the key -->
+<!-- You set it up by adding a <universalremote> block to the window or <global> section: -->
+<!-- <universalremote> -->
+<!-- <obc45>Stop</obc45> -->
+<!-- </universalremote> -->
+<!-- To find out the OBC's of your remote, try enabling the <displayremotecodes> tag in AdvancedSettings.xml -->
+
+<!-- Note that the action can be a built-in function. -->
+<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> -->
+<!-- would automatically go to My Music on the press of the B button. -->
+
+<!-- Joysticks / Gamepads: -->
+<!-- See the sample PS3 controller configuration below for the format. -->
+<!-- -->
+<!-- Joystick Name: -->
+<!-- Do 'cat /proc/bus/input/devices' or see your xbmc log file to find the names of -->
+<!-- detected joysticks. The name used in the configuration should match the detected name. -->
+<!-- -->
+<!-- Button Ids: -->
+<!-- 'id' is the button ID used by SDL. Joystick button ids of connected joysticks appear -->
+<!-- in xbmc.log when they are pressed. Use your log to map custom buttons to actions. -->
+<!-- -->
+<!-- Axis Ids / Analog Controls -->
+<!-- Coming soon. -->
+<keymap>
+ <global>
+ <keyboard>
+ <p>Play</p>
+ <q>Queue</q>
+ <f>FastForward</f>
+ <r>Rewind</r>
+ <left>Left</left>
+ <right>Right</right>
+ <up>Up</up>
+ <down>Down</down>
+ <pageup>PageUp</pageup>
+ <pagedown>PageDown</pagedown>
+ <return>Select</return>
+ <enter>Select</enter>
+ <backspace>ParentDir</backspace>
+ <m>ActivateWindow(PlayerControls)</m>
+ <s>ActivateWindow(shutdownmenu)</s>
+ <escape>PreviousMenu</escape>
+ <i>Info</i>
+ <menu>ContextMenu</menu>
+ <c>ContextMenu</c>
+ <space>Pause</space>
+ <x>Stop</x>
+ <period>SkipNext</period>
+ <comma>SkipPrevious</comma>
+ <tab>FullScreen</tab>
+ <printscreen>Screenshot</printscreen>
+ <minus>VolumeDown</minus>
+ <plus>VolumeUp</plus>
+ <zero>Number0</zero>
+ <one>Number1</one>
+ <two>Number2</two>
+ <three>Number3</three>
+ <four>Number4</four>
+ <five>Number5</five>
+ <six>Number6</six>
+ <seven>Number7</seven>
+ <eight>Number8</eight>
+ <nine>Number9</nine>
+ <backslash>ToggleFullScreen</backslash>
+ <browser_home>XBMC.ActivateWindow(Home)</browser_home>
+ <browser_favorites>ActivateWindow(Favourites)</browser_favorites>
+ <browser_refresh/>
+ <browser_search/>
+ <launch_app1_pc_icon>ActivateWindow(MyPrograms)</launch_app1_pc_icon>
+ <launch_media_select>XBMC.ActivateWindow(MyMusic)</launch_media_select>
+ <play_pause>Pause</play_pause>
+ <stop>Stop</stop>
+ <volume_up>VolumeUp</volume_up>
+ <volume_mute>Mute</volume_mute>
+ <volume_down>VolumeDown</volume_down>
+ <next_track>SkipNext</next_track>
+ <prev_track>SkipPrevious</prev_track>
+ <launch_mail/>
+ <key id='61620'/> <!-- same as above, launch_mail, but using button code (based on vkey id) -->
+ <home>FirstPage</home>
+ <end>LastPage</end>
+ <key id='65446'>ParentDir</key>
+ <key id='65459'>Play</key>
+ </keyboard>
+ </global>
+ <Home>
+ <keyboard>
+ <i>info</i>
+ <end>XBMC.ShutDown()</end>
+ </keyboard>
+ </Home>
+ <MyFiles>
+ <keyboard>
+ <space>Highlight</space>
+ <delete>Delete</delete>
+ <m>Move</m>
+ <r>Rename</r>
+ </keyboard>
+ </MyFiles>
+ <MyMusicPlaylist>
+ <keyboard>
+ <space>Playlist</space> <!-- Close playlist -->
+ <delete>Delete</delete>
+ <u>MoveItemUp</u>
+ <d>MoveItemDown</d>
+ <backspace>Playlist</backspace> <!-- Close playlist -->
+ </keyboard>
+ </MyMusicPlaylist>
+ <MyMusicPlaylistEditor>
+ <keyboard>
+ <u>MoveItemUp</u>
+ <d>MoveItemDown</d>
+ <delete>Delete</delete>
+ </keyboard>
+ </MyMusicPlaylistEditor>
+ <MyMusicFiles>
+ <keyboard>
+ <space>Playlist</space>
+ <q>Queue</q>
+ </keyboard>
+ </MyMusicFiles>
+ <MyMusicLibrary>
+ <keyboard>
+ <space>Playlist</space>
+ <q>Queue</q>
+ </keyboard>
+ </MyMusicLibrary>
+ <FullscreenVideo>
+ <keyboard>
+ <f>FastForward</f>
+ <r>Rewind</r>
+ <period>StepForward</period>
+ <comma>StepBack</comma>
+ <backspace>Fullscreen</backspace>
+ <quote>SmallStepBack</quote>
+ <opensquarebracket>BigStepForward</opensquarebracket>
+ <closesquarebracket>BigStepBack</closesquarebracket>
+ <return>OSD</return>
+ <enter>OSD</enter>
+ <m>OSD</m>
+ <i>Info</i>
+ <o>CodecInfo</o>
+ <z>AspectRatio</z>
+ <t>ShowSubtitles</t>
+ <l>NextSubtitle</l>
+ <left>StepBack</left>
+ <right>StepForward</right>
+ <up>BigStepForward</up>
+ <down>BigStepBack</down>
+ <a>AudioDelay</a>
+ <escape>Fullscreen</escape>
+ </keyboard>
+ </FullscreenVideo>
+ <FullscreenInfo>
+ <keyboard>
+ <f>FastForward</f>
+ <r>Rewind</r>
+ <period>StepForward</period>
+ <backspace>Close</backspace>
+ <o>CodecInfo</o>
+ <i>Close</i>
+ <m>OSD</m>
+ </keyboard>
+ </FullscreenInfo>
+ <PlayerControls>
+ <keyboard>
+ <escape>Close</escape>
+ <m>close</m>
+ </keyboard>
+ </PlayerControls>
+ <Visualisation>
+ <keyboard>
+ <f>FastForward</f>
+ <r>Rewind</r>
+ <period>SkipNext</period>
+ <comma>SkipPrevious</comma>
+ <return>ActivateWindow(MusicOSD)</return>
+ <enter>ActivateWindow(MusicOSD)</enter>
+ <m>ActivateWindow(MusicOSD)</m>
+ <i>Info</i>
+ <p>ActivateWindow(VisualisationPresetList)</p>
+ <v>ActivateWindow(VisualisationSettings)</v>
+ <n>ActivateWindow(MusicPlaylist)</n>
+ <left>SkipPrevious</left>
+ <right>SkipNext</right>
+ <up>IncreaseRating</up>
+ <down>DecreaseRating</down> <!--<back>NextPreset</back>!-->
+ <o>CodecInfo</o>
+ <l>LockPreset</l>
+ <escape>FullScreen</escape>
+ </keyboard>
+ </Visualisation>
+ <MusicOSD>
+ <keyboard>
+ <escape>Close</escape>
+ <f>FastForward</f>
+ <r>Rewind</r>
+ <period>SkipNext</period>
+ <comma>SkipPrevious</comma>
+ <m>Close</m>
+ <i>Info</i>
+ <o>CodecInfo</o>
+ <p>ActivateWindow(VisualisationPresetList)</p>
+ <v>ActivateWindow(VisualisationSettings)</v>
+ <n>ActivateWindow(MusicPlaylist)</n>
+ </keyboard>
+ </MusicOSD>
+ <VisualisationSettings>
+ <keyboard>
+ <escape>Close</escape>
+ <f>FastForward</f>
+ <r>Rewind</r>
+ <period>SkipNext</period>
+ <comma>SkipPrevious</comma>
+ <m>Close</m>
+ <i>Info</i>
+ <o>CodecInfo</o>
+ <p>ActivateWindow(VisualisationPresetList)</p>
+ <v>Close</v>
+ <n>ActivateWindow(MusicPlaylist)</n>
+ </keyboard>
+ </VisualisationSettings>
+ <VisualisationPresetList>
+ <keyboard>
+ <escape>Close</escape>
+ <f>FastForward</f>
+ <r>Rewind</r>
+ <period>SkipNext</period>
+ <comma>SkipPrevious</comma>
+ <m>Close</m>
+ <i>Info</i>
+ <o>CodecInfo</o>
+ <p>Close</p>
+ <v>Close</v>
+ <n>ActivateWindow(MusicPlaylist)</n>
+ </keyboard>
+ </VisualisationPresetList>
+ <SlideShow>
+ <keyboard>
+ <zero>ZoomNormal</zero>
+ <one>ZoomLevel1</one>
+ <two>ZoomLevel2</two>
+ <three>ZoomLevel3</three>
+ <four>ZoomLevel4</four>
+ <five>ZoomLevel5</five>
+ <six>ZoomLevel6</six>
+ <seven>ZoomLevel7</seven>
+ <eight>ZoomLevel8</eight>
+ <nine>ZoomLevel9</nine>
+ <i>Info</i>
+ <o>CodecInfo</o>
+ <period>NextPicture</period>
+ <comma>PreviousPicture</comma>
+ <plus>ZoomIn</plus>
+ <minus>ZoomOut</minus>
+ <r>Rotate</r>
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </SlideShow>
+ <ScreenCalibration>
+ <keyboard>
+ <return>NextCalibration</return>
+ <enter>NextCalibration</enter>
+ <d>ResetCalibration</d>
+ <r>NextResolution</r>
+ </keyboard>
+ </ScreenCalibration>
+ <GUICalibration>
+ <keyboard>
+ <return>NextCalibration</return>
+ <enter>NextCalibration</enter>
+ <d>ResetCalibration</d>
+ </keyboard>
+ </GUICalibration>
+ <SelectDialog>
+ <keyboard>
+ <backspace>Close</backspace>
+ <escape>Close</escape>
+ </keyboard>
+ </SelectDialog>
+ <VideoOSD>
+ <keyboard>
+ <backspace>Close</backspace>
+ <escape>Close</escape>
+ <m>Close</m>
+ <i>Info</i>
+ <o>CodecInfo</o>
+ </keyboard>
+ </VideoOSD>
+ <VideoMenu>
+ <keyboard>
+ <opensquarebracket>BigStepForward</opensquarebracket>
+ <closesquarebracket>BigStepBack</closesquarebracket>
+ <m>OSD</m>
+ <i>Info</i>
+ <o>CodecInfo</o>
+ <z>AspectRatio</z>
+ <t>ShowSubtitles</t>
+ <l>NextSubtitle</l>
+ <a>AudioDelay</a>
+ <escape>Fullscreen</escape>
+ <return>Select</return>
+ <enter>Select</enter> <!-- backspace>Fullscreen</backspace -->
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </VideoMenu>
+ <OSDVideoSettings>
+ <keyboard>
+ <backspace>Close</backspace>
+ <escape>Close</escape>
+ <i>Info</i>
+ <o>CodecInfo</o>
+ </keyboard>
+ </OSDVideoSettings>
+ <OSDAudioSettings>
+ <keyboard>
+ <backspace>Close</backspace>
+ <escape>Close</escape>
+ <i>Info</i>
+ <o>CodecInfo</o>
+ </keyboard>
+ </OSDAudioSettings>
+ <VideoBookmarks>
+ <keyboard>
+ <backspace>Close</backspace>
+ <escape>Close</escape>
+ </keyboard>
+ </VideoBookmarks>
+ <MyVideoLibrary>
+ <keyboard>
+ <delete>Delete</delete>
+ <space>Playlist</space>
+ <w>ToggleWatched</w>
+ </keyboard>
+ </MyVideoLibrary>
+ <MyVideoFiles>
+ <keyboard>
+ <space>Playlist</space>
+ <q>Queue</q>
+ </keyboard>
+ </MyVideoFiles>
+ <MyVideoPlaylist>
+ <keyboard>
+ <backspace>Playlist</backspace> <!-- Close playlist -->
+ <space>Playlist</space> <!-- Close playlist -->
+ <delete>Delete</delete>
+ <u>MoveItemUp</u>
+ <d>MoveItemDown</d>
+ </keyboard>
+ </MyVideoPlaylist>
+ <ContextMenu>
+ <keyboard>
+ <c>Close</c>
+ <menu>Close</menu>
+ <backspace>Close</backspace>
+ </keyboard>
+ </ContextMenu>
+ <FileStackingDialog>
+ <keyboard>
+ <backspace>Close</backspace>
+ </keyboard>
+ </FileStackingDialog>
+ <Scripts>
+ <keyboard>
+ <i>XBMC.ActivateWindow(ScriptsDebugInfo)</i>
+ </keyboard>
+ </Scripts>
+ <ScriptsDebugInfo>
+ <keyboard>
+ <i>Info</i> <!-- clears debug python info -->
+ </keyboard>
+ </ScriptsDebugInfo>
+ <Weather>
+ <keyboard>
+ <backspace>PreviousMenu</backspace>
+ <key id='65446'>PreviousMenu</key>
+ </keyboard>
+ </Weather>
+ <Settings>
+ <keyboard>
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </Settings>
+ <MyPicturesSettings>
+ <keyboard>
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </MyPicturesSettings>
+ <MyProgramsSettings>
+ <keyboard>
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </MyProgramsSettings>
+ <MyWeatherSettings>
+ <keyboard>
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </MyWeatherSettings>
+ <MyMusicSettings>
+ <keyboard>
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </MyMusicSettings>
+ <SystemSettings>
+ <keyboard>
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </SystemSettings>
+ <MyVideosSettings>
+ <keyboard>
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </MyVideosSettings>
+ <NetworkSettings>
+ <keyboard>
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </NetworkSettings>
+ <AppearanceSettings>
+ <keyboard>
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </AppearanceSettings>
+ <Profiles>
+ <keyboard>
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </Profiles>
+ <systeminfo>
+ <keyboard>
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </systeminfo>
+ <shutdownmenu>
+ <keyboard>
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </shutdownmenu>
+ <submenu>
+ <keyboard>
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </submenu>
+ <MusicInformation>
+ <keyboard>
+ <backspace>Close</backspace>
+ <key id='65446'>Close</key>
+ </keyboard>
+ </MusicInformation>
+ <MovieInformation>
+ <keyboard>
+ <backspace>Close</backspace>
+ <key id='65446'>Close</key>
+ </keyboard>
+ </MovieInformation>
+ <LockSettings>
+ <keyboard>
+ <escape>Close</escape>
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </LockSettings>
+ <ProfileSettings>
+ <keyboard>
+ <escape>Close</escape>
+ <backspace>PreviousMenu</backspace>
+ </keyboard>
+ </ProfileSettings>
+ <PictureInfo>
+ <keyboard>
+ <period>NextPicture</period>
+ <comma>PreviousPicture</comma>
+ <i>Close</i>
+ <o>Close</o>
+ <backspace>Close</backspace>
+ <space>Pause</space>
+ </keyboard>
+ </PictureInfo>
+ <Favourites>
+ <keyboard>
+ <backspace>Close</backspace>
+ </keyboard>
+ </Favourites>
+</keymap>
diff --git a/system/keymaps/remote.xml b/system/keymaps/remote.xml
new file mode 100644
index 0000000000..c35556de93
--- /dev/null
+++ b/system/keymaps/remote.xml
@@ -0,0 +1,453 @@
+<!-- This file contains the mapping of keys (gamepad, remote, and keyboard) to actions within XBMC -->
+<!-- The <global> section is a fall through - they will only be used if the button is not -->
+<!-- used in the current window's section. Note that there is only handling -->
+<!-- for a single action per button at this stage. -->
+<!-- For joystick/gamepad configuration under linux/win32, see below as it differs from xbox -->
+<!-- gamepads. -->
+
+<!-- The format is: -->
+<!-- <device> -->
+<!-- <button>action</button> -->
+<!-- </device> -->
+
+<!-- To map keys from other remotes using the RCA protocol, you may add <universalremote> blocks -->
+<!-- In this case, the tags used are <obc#> where # is the original button code (OBC) of the key -->
+<!-- You set it up by adding a <universalremote> block to the window or <global> section: -->
+<!-- <universalremote> -->
+<!-- <obc45>Stop</obc45> -->
+<!-- </universalremote> -->
+<!-- To find out the OBC's of your remote, try enabling the <displayremotecodes> tag in AdvancedSettings.xml -->
+
+<!-- Note that the action can be a built-in function. -->
+<!-- eg <B>XBMC.ActivateWindow(MyMusic)</B> -->
+<!-- would automatically go to My Music on the press of the B button. -->
+
+<!-- Joysticks / Gamepads: -->
+<!-- See the sample PS3 controller configuration below for the format. -->
+<!-- -->
+<!-- Joystick Name: -->
+<!-- Do 'cat /proc/bus/input/devices' or see your xbmc log file to find the names of -->
+<!-- detected joysticks. The name used in the configuration should match the detected name. -->
+<!-- -->
+<!-- Button Ids: -->
+<!-- 'id' is the button ID used by SDL. Joystick button ids of connected joysticks appear -->
+<!-- in xbmc.log when they are pressed. Use your log to map custom buttons to actions. -->
+<!-- -->
+<!-- Axis Ids / Analog Controls -->
+<!-- Coming soon. -->
+<keymap>
+ <global>
+ <remote>
+ <play>Play</play>
+ <pause>Pause</pause>
+ <stop>Stop</stop>
+ <forward>FastForward</forward>
+ <reverse>Rewind</reverse>
+ <left>Left</left>
+ <right>Right</right>
+ <up>Up</up>
+ <down>Down</down>
+ <select>Select</select>
+ <pageplus>PageUp</pageplus>
+ <pageminus>PageDown</pageminus>
+ <back>ParentDir</back>
+ <menu>PreviousMenu</menu>
+ <title>ContextMenu</title>
+ <info>Info</info>
+ <skipplus>SkipNext</skipplus>
+ <skipminus>SkipPrevious</skipminus>
+ <display>FullScreen</display>
+ <start>PreviousMenu</start>
+ <record>Screenshot</record>
+ <volumeplus>VolumeUp</volumeplus>
+ <volumeminus>VolumeDown</volumeminus>
+ <mute>Mute</mute>
+ <power>XBMC.ShutDown()</power>
+ <myvideo>XBMC.ActivateWindow(MyVideos)</myvideo>
+ <mymusic>XBMC.ActivateWindow(MyMusic)</mymusic>
+ <mypictures>XBMC.ActivateWindow(MyPictures)</mypictures>
+ <mytv>XBMC.ActivateWindow(Home)</mytv>
+ <zero>Number0</zero>
+ <one>Number1</one>
+ <two>JumpSMS2</two>
+ <three>JumpSMS3</three>
+ <four>JumpSMS4</four>
+ <five>JumpSMS5</five>
+ <six>JumpSMS6</six>
+ <seven>JumpSMS7</seven>
+ <eight>JumpSMS8</eight>
+ <nine>JumpSMS9</nine>
+ </remote>
+ </global>
+ <Home>
+ <remote>
+ <menu>XBMC.Skin.ToggleSetting(HomeViewToggle)</menu>
+ <info>XBMC.ActivateWindow(SystemInfo)</info>
+ <clear>XBMC.ActivateWindow(Weather)</clear>
+ <hash>XBMC.ActivateWindow(Settings)</hash>
+ </remote>
+ </Home>
+ <MyFiles>
+ <remote>
+ <clear>Delete</clear>
+ </remote>
+ </MyFiles>
+ <MyMusicPlaylist>
+ <remote>
+ <back>Playlist</back> <!-- Close playlist -->
+ <clear>Delete</clear>
+ </remote>
+ </MyMusicPlaylist>
+ <MyMusicPlaylistEditor>
+ <remote>
+ <zero>Queue</zero>
+ </remote>
+ </MyMusicPlaylistEditor>
+ <MyMusicFiles>
+ <remote>
+ <zero>Queue</zero>
+ <star>Queue</star>
+ </remote>
+ </MyMusicFiles>
+ <MyMusicLibrary>
+ <remote>
+ <zero>Queue</zero>
+ <star>Queue</star>
+ </remote>
+ </MyMusicLibrary>
+ <FullscreenVideo>
+ <remote>
+ <zero>Number0</zero>
+ <one>Number1</one>
+ <two>Number2</two>
+ <three>Number3</three>
+ <four>Number4</four>
+ <five>Number5</five>
+ <six>Number6</six>
+ <seven>Number7</seven>
+ <eight>Number8</eight>
+ <nine>Number9</nine>
+ <left>StepBack</left>
+ <right>StepForward</right>
+ <up>BigStepForward</up>
+ <down>BigStepBack</down>
+ <back>SmallStepBack</back>
+ <menu>OSD</menu>
+ <start>OSD</start>
+ <title>CodecInfo</title>
+ <info>Info</info>
+ <enter>AspectRatio</enter>
+ <select>AspectRatio</select>
+ </remote>
+ </FullscreenVideo>
+ <FullscreenInfo>
+ <remote>
+ <title>CodecInfo</title>
+ <info>Close</info>
+ <menu>OSD</menu>
+ </remote>
+ </FullscreenInfo>
+ <PlayerControls>
+ <remote>
+ <menu>Close</menu>
+ </remote>
+ </PlayerControls>
+ <Visualisation>
+ <remote>
+ <left>PreviousPreset</left>
+ <right>NextPreset</right>
+ <up>IncreaseRating</up>
+ <down>DecreaseRating</down>
+ <back>LockPreset</back>
+ <title>CodecInfo</title>
+ <select>XBMC.ActivateWindow(VisualisationPresetList)</select>
+ <menu>XBMC.ActivateWindow(MusicOSD)</menu>
+ <start>XBMC.ActivateWindow(MusicOSD)</start>
+ <info>Info</info>
+ </remote>
+ </Visualisation>
+ <MusicOSD>
+ <remote>
+ <menu>Close</menu>
+ <title>Info</title>
+ <info>CodecInfo</info>
+ </remote>
+ </MusicOSD>
+ <VisualisationSettings>
+ <remote>
+ <menu>Close</menu>
+ </remote>
+ </VisualisationSettings>
+ <VisualisationPresetList>
+ <remote>
+ <menu>Close</menu>
+ </remote>
+ </VisualisationPresetList>
+ <SlideShow>
+ <remote>
+ <zero>ZoomNormal</zero>
+ <one>ZoomLevel1</one>
+ <two>ZoomLevel2</two>
+ <three>ZoomLevel3</three>
+ <four>ZoomLevel4</four>
+ <five>ZoomLevel5</five>
+ <six>ZoomLevel6</six>
+ <seven>ZoomLevel7</seven>
+ <eight>ZoomLevel8</eight>
+ <nine>ZoomLevel9</nine>
+ <info>CodecInfo</info>
+ <skipplus>NextPicture</skipplus>
+ <skipminus>PreviousPicture</skipminus>
+ <title>Info</title>
+ <select>Rotate</select>
+ <back>PreviousMenu</back>
+ </remote>
+ </SlideShow>
+ <ScreenCalibration>
+ <remote>
+ <select>NextCalibration</select>
+ <enter>NextCalibration</enter>
+ <zero>ResetCalibration</zero>
+ <display>NextResolution</display>
+ <xbox>NextResolution</xbox>
+ </remote>
+ </ScreenCalibration>
+ <GUICalibration>
+ <remote>
+ <select>NextCalibration</select>
+ <enter>NextCalibration</enter>
+ <zero>ResetCalibration</zero>
+ </remote>
+ </GUICalibration>
+ <SelectDialog>
+ <remote>
+ <back>Close</back>
+ </remote>
+ </SelectDialog>
+ <VideoOSD>
+ <remote>
+ <back>PreviousMenu</back>
+ <menu>Close</menu>
+ <start>Close</start>
+ </remote>
+ </VideoOSD>
+ <VideoMenu>
+ <remote>
+ <menu>OSD</menu>
+ <back>PreviousMenu</back>
+ <info>Info</info>
+ <title>CodecInfo</title>
+ <zero>Number0</zero>
+ <one>Number1</one>
+ <two>Number2</two>
+ <three>Number3</three>
+ <four>Number4</four>
+ <five>Number5</five>
+ <six>Number6</six>
+ <seven>Number7</seven>
+ <eight>Number8</eight>
+ <nine>Number9</nine>
+ </remote>
+ </VideoMenu>
+ <OSDVideoSettings>
+ <remote>
+ <back>Close</back>
+ <menu>Close</menu>
+ <start>Close</start>
+ </remote>
+ </OSDVideoSettings>
+ <OSDAudioSettings>
+ <remote>
+ <back>Close</back>
+ <menu>Close</menu>
+ <start>Close</start>
+ </remote>
+ </OSDAudioSettings>
+ <VideoBookmarks>
+ <remote>
+ <back>Close</back>
+ <menu>Close</menu>
+ <start>Close</start>
+ <zero>Delete</zero>
+ </remote>
+ </VideoBookmarks>
+ <MyVideoLibrary>
+ <remote>
+ <zero>Queue</zero>
+ <clear>Delete</clear>
+ </remote>
+ </MyVideoLibrary>
+ <MyVideoFiles>
+ <remote>
+ <zero>Queue</zero>
+ <star>Queue</star>
+ </remote>
+ </MyVideoFiles>
+ <MyVideoPlaylist>
+ <remote>
+ <back>Playlist</back> <!-- Close playlist -->
+ <clear>Delete</clear>
+ <zero>Delete</zero>
+ </remote>
+ </MyVideoPlaylist>
+ <VirtualKeyboard>
+ <remote>
+ <back>BackSpace</back>
+ <star>Shift</star>
+ <hash>Symbols</hash>
+ <zero>Number0</zero>
+ <one>Number1</one>
+ <two>Number2</two>
+ <three>Number3</three>
+ <four>Number4</four>
+ <five>Number5</five>
+ <six>Number6</six>
+ <seven>Number7</seven>
+ <eight>Number8</eight>
+ <nine>Number9</nine>
+ <pageminus>CursorLeft</pageminus>
+ <pageplus>CursorRight</pageplus>
+ </remote>
+ </VirtualKeyboard>
+ <ContextMenu>
+ <remote>
+ <title>Close</title>
+ <back>Close</back>
+ </remote>
+ </ContextMenu>
+ <FileStackingDialog>
+ <remote>
+ <back>Close</back>
+ </remote>
+ </FileStackingDialog>
+ <Scripts>
+ <remote>
+ <info>XBMC.ActivateWindow(ScriptsDebugInfo)</info>
+ </remote>
+ </Scripts>
+ <ScriptsDebugInfo>
+ <remote>
+ <info>Info</info> <!-- clears debug python info -->
+ </remote>
+ </ScriptsDebugInfo>
+ <NumericInput>
+ <remote>
+ <zero>Number0</zero>
+ <one>Number1</one>
+ <two>Number2</two>
+ <three>Number3</three>
+ <four>Number4</four>
+ <five>Number5</five>
+ <six>Number6</six>
+ <seven>Number7</seven>
+ <eight>Number8</eight>
+ <nine>Number9</nine>
+ <back>BackSpace</back>
+ </remote>
+ </NumericInput>
+ <Weather>
+ <remote>
+ <back>PreviousMenu</back>
+ </remote>
+ </Weather>
+ <Settings>
+ <remote>
+ <back>PreviousMenu</back>
+ </remote>
+ </Settings>
+ <MyPicturesSettings>
+ <remote>
+ <back>PreviousMenu</back>
+ </remote>
+ </MyPicturesSettings>
+ <MyProgramsSettings>
+ <remote>
+ <back>PreviousMenu</back>
+ </remote>
+ </MyProgramsSettings>
+ <MyWeatherSettings>
+ <remote>
+ <back>PreviousMenu</back>
+ </remote>
+ </MyWeatherSettings>
+ <MyMusicSettings>
+ <remote>
+ <back>PreviousMenu</back>
+ </remote>
+ </MyMusicSettings>
+ <SystemSettings>
+ <remote>
+ <back>PreviousMenu</back>
+ </remote>
+ </SystemSettings>
+ <MyVideosSettings>
+ <remote>
+ <back>PreviousMenu</back>
+ </remote>
+ </MyVideosSettings>
+ <NetworkSettings>
+ <remote>
+ <back>PreviousMenu</back>
+ </remote>
+ </NetworkSettings>
+ <AppearanceSettings>
+ <remote>
+ <back>PreviousMenu</back>
+ </remote>
+ </AppearanceSettings>
+ <Profiles>
+ <remote>
+ <back>PreviousMenu</back>
+ </remote>
+ </Profiles>
+ <systeminfo>
+ <remote>
+ <back>PreviousMenu</back>
+ </remote>
+ </systeminfo>
+ <shutdownmenu>
+ <remote>
+ <back>PreviousMenu</back>
+ </remote>
+ </shutdownmenu>
+ <submenu>
+ <remote>
+ <back>PreviousMenu</back>
+ </remote>
+ </submenu>
+ <MusicInformation>
+ <remote>
+ <back>Close</back>
+ </remote>
+ </MusicInformation>
+ <MovieInformation>
+ <remote>
+ <back>Close</back>
+ </remote>
+ </MovieInformation>
+ <LockSettings>
+ <remote>
+ <menu>Close</menu>
+ <back>PreviousMenu</back>
+ </remote>
+ </LockSettings>
+ <ProfileSettings>
+ <remote>
+ <menu>Close</menu>
+ <back>PreviousMenu</back>
+ </remote>
+ </ProfileSettings>
+ <PictureInfo>
+ <remote>
+ <skipplus>NextPicture</skipplus>
+ <skipminus>PreviousPicture</skipminus>
+ <info>Close</info>
+ <back>Close</back>
+ </remote>
+ </PictureInfo>
+ <Favourites>
+ <remote>
+ <back>Close</back>
+ </remote>
+ </Favourites>
+</keymap>
diff --git a/system/libcmyth.dll b/system/libcmyth.dll
new file mode 100644
index 0000000000..6f51fcd93f
--- /dev/null
+++ b/system/libcmyth.dll
Binary files differ
diff --git a/system/libcurl-powerpc-osx.so b/system/libcurl-powerpc-osx.so
new file mode 100755
index 0000000000..8620c894cc
--- /dev/null
+++ b/system/libcurl-powerpc-osx.so
Binary files differ
diff --git a/system/libcurl-x86-osx.so b/system/libcurl-x86-osx.so
new file mode 100755
index 0000000000..5a8695ef59
--- /dev/null
+++ b/system/libcurl-x86-osx.so
Binary files differ
diff --git a/system/libcurl.dll b/system/libcurl.dll
new file mode 100644
index 0000000000..ad011b28b7
--- /dev/null
+++ b/system/libcurl.dll
Binary files differ
diff --git a/system/libexif.dll b/system/libexif.dll
new file mode 100644
index 0000000000..74d1a3dde9
--- /dev/null
+++ b/system/libexif.dll
Binary files differ
diff --git a/system/libid3tag.dll b/system/libid3tag.dll
new file mode 100644
index 0000000000..96f78c20e9
--- /dev/null
+++ b/system/libid3tag.dll
Binary files differ
diff --git a/system/playercorefactory.xml b/system/playercorefactory.xml
new file mode 100644
index 0000000000..b81df8fe09
--- /dev/null
+++ b/system/playercorefactory.xml
@@ -0,0 +1,37 @@
+<playercorefactory>
+ <players>
+ <!-- These are compiled-in as re-ordering them would break scripts
+ The following aliases may also be used:
+ audiodefaultplayer, videodefaultplayer, videodefaultdvdplayer
+ <player name="DVDPlayer" audio="true" video="true" />
+ <player name="DVDPlayer" /> placeholder for MPlayer
+ <player name="PAPlayer" audio="true" />
+ -->
+ </players>
+
+ <rules name="system rules">
+ <rule name="rtv" protocols="rtv" player="DVDPlayer" />
+ <rule name="hdhomerun/myth/rtmp/mms" protocols="hdhomerun|myth|cmyth|rtmp|mms|mmsh" player="DVDPlayer" />
+ <rule name="lastfm/shout" protocols="lastfm|shout" player="PAPlayer" />
+
+ <!-- dvdplayer can play standard rtsp streams -->
+ <rule name="rtsp" protocols="rtsp" filetypes="!(rm|ra)" player="PAPlayer" />
+
+ <!-- Internet streams -->
+ <rule name="streams" internetstream="true">
+ <rule name="flv/aacp/sdp" mimetypes="video/x-flv|video-flv|audio/aacp|application/sdp" player="DVDPlayer" />
+ <rule name="mp2" mimetypes="application/octet-stream" filetypes="mp2" player="PAPlayer" />
+ </rule>
+
+ <!-- DVDs -->
+ <rule name="dvd" dvd="true" player="videodefaultdvdplayer" />
+ <rule name="dvdfile" dvdfile="true" player="videodefaultdvdplayer" />
+ <rule name="dvdimage" dvdimage="true" player="videodefaultdvdplayer" />
+
+ <!-- Only dvdplayer can handle these normally -->
+ <rule name="sdp/asf" filetypes="sdp|asf" player="DVDPlayer" />
+
+ <!-- Pass these to dvdplayer as we do not know if they are audio or video -->
+ <rule name="nsv" filetypes="nsv" player="DVDPlayer" />
+ </rules>
+</playercorefactory>
diff --git a/system/players/dvdplayer/avcodec-52.dll b/system/players/dvdplayer/avcodec-52.dll
new file mode 100644
index 0000000000..6c5f2723bd
--- /dev/null
+++ b/system/players/dvdplayer/avcodec-52.dll
Binary files differ
diff --git a/system/players/dvdplayer/avformat-52.dll b/system/players/dvdplayer/avformat-52.dll
new file mode 100644
index 0000000000..ef60659e92
--- /dev/null
+++ b/system/players/dvdplayer/avformat-52.dll
Binary files differ
diff --git a/system/players/dvdplayer/avutil-50.dll b/system/players/dvdplayer/avutil-50.dll
new file mode 100644
index 0000000000..a5bd5b5223
--- /dev/null
+++ b/system/players/dvdplayer/avutil-50.dll
Binary files differ
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/10-autohint.conf b/system/players/dvdplayer/etc/fonts/conf.avail/10-autohint.conf
new file mode 100644
index 0000000000..5406f4eddb
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/10-autohint.conf
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- debian/autohint.conf -->
+<fontconfig>
+<!-- Use the Autohinter -->
+ <match target="font">
+ <edit name="autohint" mode="assign"><bool>true</bool></edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/10-no-sub-pixel.conf b/system/players/dvdplayer/etc/fonts/conf.avail/10-no-sub-pixel.conf
new file mode 100644
index 0000000000..5d64a0b433
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/10-no-sub-pixel.conf
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- conf.d/sub-pixel.conf -->
+<fontconfig>
+<!-- Enable sub-pixel rendering -->
+ <match target="font">
+ <edit name="rgba" mode="assign"><const>none</const></edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/10-sub-pixel-bgr.conf b/system/players/dvdplayer/etc/fonts/conf.avail/10-sub-pixel-bgr.conf
new file mode 100644
index 0000000000..2aba95e13d
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/10-sub-pixel-bgr.conf
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- conf.d/sub-pixel.conf -->
+<fontconfig>
+<!-- Enable sub-pixel rendering -->
+ <match target="font">
+ <edit name="rgba" mode="assign"><const>bgr</const></edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/10-sub-pixel-rgb.conf b/system/players/dvdplayer/etc/fonts/conf.avail/10-sub-pixel-rgb.conf
new file mode 100644
index 0000000000..c4e8a42e1c
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/10-sub-pixel-rgb.conf
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- conf.d/sub-pixel.conf -->
+<fontconfig>
+<!-- Enable sub-pixel rendering -->
+ <match target="font">
+ <edit name="rgba" mode="assign"><const>rgb</const></edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/10-sub-pixel-vbgr.conf b/system/players/dvdplayer/etc/fonts/conf.avail/10-sub-pixel-vbgr.conf
new file mode 100644
index 0000000000..0cdad2a700
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/10-sub-pixel-vbgr.conf
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- conf.d/sub-pixel.conf -->
+<fontconfig>
+<!-- Enable sub-pixel rendering -->
+ <match target="font">
+ <edit name="rgba" mode="assign"><const>vbgr</const></edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/10-sub-pixel-vrgb.conf b/system/players/dvdplayer/etc/fonts/conf.avail/10-sub-pixel-vrgb.conf
new file mode 100644
index 0000000000..60239e0254
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/10-sub-pixel-vrgb.conf
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- conf.d/sub-pixel.conf -->
+<fontconfig>
+<!-- Enable sub-pixel rendering -->
+ <match target="font">
+ <edit name="rgba" mode="assign"><const>vrgb</const></edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/10-unhinted.conf b/system/players/dvdplayer/etc/fonts/conf.avail/10-unhinted.conf
new file mode 100644
index 0000000000..fb0b375acd
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/10-unhinted.conf
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- debian/unhinted.conf -->
+<fontconfig>
+<!-- Disable hinting -->
+ <match target="font">
+ <edit name="hinting" mode="assign"><bool>false</bool></edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/20-fix-globaladvance.conf b/system/players/dvdplayer/etc/fonts/conf.avail/20-fix-globaladvance.conf
new file mode 100644
index 0000000000..a62162ca0f
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/20-fix-globaladvance.conf
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- conf.d/sub-pixel.conf -->
+<fontconfig>
+<!--
+ Some Asian fonts misadvertise themselves as monospaced when
+ in fact they are dual-spaced (half and full). This makes
+ FreeType very confused as it forces all widths to match.
+ Undo this magic by disabling the width forcing code -->
+ <match target="font">
+ <test name="family"><string>GulimChe</string></test>
+ <edit name="globaladvance"><bool>false</bool></edit>
+ </match>
+
+ <match target="font">
+ <test name="family"><string>DotumChe</string></test>
+ <edit name="globaladvance"><bool>false</bool></edit>
+ </match>
+
+ <match target="font">
+ <test name="family"><string>BatangChe</string></test>
+ <edit name="globaladvance"><bool>false</bool></edit>
+ </match>
+
+ <match target="font">
+ <test name="family"><string>GungsuhChe</string></test>
+ <edit name="globaladvance"><bool>false</bool></edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/20-lohit-gujarati.conf b/system/players/dvdplayer/etc/fonts/conf.avail/20-lohit-gujarati.conf
new file mode 100644
index 0000000000..1c29d0d0ad
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/20-lohit-gujarati.conf
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+
+<!-- Available Gujarti fonts look much better without hinting -->
+
+ <match target="font">
+ <test name="family"><string>Lohit Gujarati</string></test>
+ <edit name="hinting"><bool>false</bool></edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/20-unhint-small-vera.conf b/system/players/dvdplayer/etc/fonts/conf.avail/20-unhint-small-vera.conf
new file mode 100644
index 0000000000..3078119803
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/20-unhint-small-vera.conf
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- conf.d/sub-pixel.conf -->
+<fontconfig>
+<!--
+ The Bitstream Vera fonts have GASP entries suggesting that hinting be
+ disabled below 8 ppem, but FreeType ignores those, preferring to use
+ the data found in the instructed hints. The initial Vera release
+ didn't include the right instructions in the 'prep' table. Fix this
+ by disabling hinting manually at smaller sizes (< 8ppem)
+ -->
+
+ <match target="font">
+ <test name="family">
+ <string>Bitstream Vera Sans</string>
+ </test>
+ <test name="pixelsize" compare="less">
+ <double>7.5</double>
+ </test>
+ <edit name="hinting">
+ <bool>false</bool>
+ </edit>
+ </match>
+
+ <match target="font">
+ <test name="family">
+ <string>Bitstream Vera Serif</string>
+ </test>
+ <test name="pixelsize" compare="less">
+ <double>7.5</double>
+ </test>
+ <edit name="hinting">
+ <bool>false</bool>
+ </edit>
+ </match>
+
+ <match target="font">
+ <test name="family">
+ <string>Bitstream Vera Sans Mono</string>
+ </test>
+ <test name="pixelsize" compare="less">
+ <double>7.5</double>
+ </test>
+ <edit name="hinting">
+ <bool>false</bool>
+ </edit>
+ </match>
+
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/30-amt-aliases.conf b/system/players/dvdplayer/etc/fonts/conf.avail/30-amt-aliases.conf
new file mode 100644
index 0000000000..d6df67e055
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/30-amt-aliases.conf
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- conf.d/sub-pixel.conf -->
+<fontconfig>
+<!--
+ AMT provides metric and shape compatible fonts for these three web font
+ families.
+ -->
+ <alias>
+ <family>Times New Roman</family>
+ <accept><family>Thorndale AMT</family></accept>
+ </alias>
+ <alias>
+ <family>Arial</family>
+ <accept><family>Albany AMT</family></accept>
+ </alias>
+ <alias>
+ <family>Courier New</family>
+ <accept><family>Cumberland AMT</family></accept>
+ </alias>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/30-urw-aliases.conf b/system/players/dvdplayer/etc/fonts/conf.avail/30-urw-aliases.conf
new file mode 100644
index 0000000000..cf90dd5466
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/30-urw-aliases.conf
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- conf.d/sub-pixel.conf -->
+<fontconfig>
+<!--
+ URW provides metric and shape compatible fonts for these 10 Adobe families.
+ -->
+ <alias>
+ <family>Avant Garde</family>
+ <accept><family>URW Gothic L</family></accept>
+ </alias>
+ <alias>
+ <family>Bookman</family>
+ <accept><family>URW Bookman L</family></accept>
+ </alias>
+ <alias>
+ <family>Courier</family>
+ <accept><family>Nimbus Mono L</family></accept>
+ </alias>
+ <alias>
+ <family>Helvetica</family>
+ <accept><family>Nimbus Sans L</family></accept>
+ </alias>
+ <alias>
+ <family>New Century Schoolbook</family>
+ <accept><family>Century Schoolbook L</family></accept>
+ </alias>
+ <alias>
+ <family>Palatino</family>
+ <accept><family>URW Palladio L</family></accept>
+ </alias>
+ <alias>
+ <family>Times</family>
+ <accept><family>Nimbus Roman No9 L</family></accept>
+ </alias>
+ <alias>
+ <family>Zapf Chancery</family>
+ <accept><family>URW Chancery L</family></accept>
+ </alias>
+ <alias>
+ <family>Zapf Dingbats</family>
+ <accept><family>Dingbats</family></accept>
+ </alias>
+ <match target="pattern">
+ <test name="family">
+ <string>Symbol</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Standard Symbols L</string>
+ </edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/40-generic.conf b/system/players/dvdplayer/etc/fonts/conf.avail/40-generic.conf
new file mode 100644
index 0000000000..84e85e44bb
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/40-generic.conf
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+<!--
+ Mark common families with their generics so we'll get
+ something reasonable
+-->
+
+<!--
+ Serif faces
+ -->
+ <alias>
+ <family>Bitstream Vera Serif</family>
+ <family>DejaVu Serif</family>
+ <family>Times New Roman</family>
+ <family>Times</family>
+ <family>Nimbus Roman No9 L</family>
+ <family>Luxi Serif</family>
+ <family>Kochi Mincho</family>
+ <family>AR PL SungtiL GB</family>
+ <family>AR PL Mingti2L Big5</family>
+ <family>пј­пјі жЋжњќ</family>
+ <family>Baekmuk Batang</family>
+ <family>FreeSerif</family>
+ <family>MgOpen Canonica</family>
+ <default><family>serif</family></default>
+ </alias>
+<!--
+ Sans-serif faces
+ -->
+ <alias>
+ <family>Bitstream Vera Sans</family>
+ <family>DejaVu Sans</family>
+ <family>Helvetica</family>
+ <family>Arial</family>
+ <family>Verdana</family>
+ <family>Albany AMT</family>
+ <family>Nimbus Sans L</family>
+ <family>Luxi Sans</family>
+ <family>Kochi Gothic</family>
+ <family>AR PL KaitiM GB</family>
+ <family>AR PL KaitiM Big5</family>
+ <family>пј­пјі г‚ґг‚·гѓѓг‚Ї</family>
+ <family>Baekmuk Dotum</family>
+ <family>SimSun</family>
+ <family>FreeSans</family>
+ <family>MgOpen Modata</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+<!--
+ Monospace faces
+ -->
+ <alias>
+ <family>Bitstream Vera Sans Mono</family>
+ <family>DejaVu Sans Mono</family>
+ <family>Courier</family>
+ <family>Courier New</family>
+ <family>Andale Mono</family>
+ <family>Luxi Mono</family>
+ <family>Cumberland AMT</family>
+ <family>Nimbus Mono L</family>
+ <family>NSimSun</family>
+ <family>FreeMono</family>
+ <default><family>monospace</family></default>
+ </alias>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/49-sansserif.conf b/system/players/dvdplayer/etc/fonts/conf.avail/49-sansserif.conf
new file mode 100644
index 0000000000..c6209a7d31
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/49-sansserif.conf
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+<!--
+ If the font still has no generic name, add sans-serif
+ -->
+ <match target="pattern">
+ <test qual="all" name="family" compare="not_eq">
+ <string>sans-serif</string>
+ </test>
+ <test qual="all" name="family" compare="not_eq">
+ <string>serif</string>
+ </test>
+ <test qual="all" name="family" compare="not_eq">
+ <string>monospace</string>
+ </test>
+ <edit name="family" mode="append_last">
+ <string>sans-serif</string>
+ </edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/50-user.conf b/system/players/dvdplayer/etc/fonts/conf.avail/50-user.conf
new file mode 100644
index 0000000000..9a38a40ad9
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/50-user.conf
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- /etc/fonts/conf.avail/50-user.conf file to configure system font access -->
+<fontconfig>
+ <!-- Load per-user customization file -->
+ <include ignore_missing="yes">~/.fonts.conf</include>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/51-local.conf b/system/players/dvdplayer/etc/fonts/conf.avail/51-local.conf
new file mode 100644
index 0000000000..d35046e78b
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/51-local.conf
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- /etc/fonts/conf.avail/51-local.conf file to configure system font access -->
+<fontconfig>
+ <!-- Load local system customization file -->
+ <include ignore_missing="yes">local.conf</include>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/60-latin.conf b/system/players/dvdplayer/etc/fonts/conf.avail/60-latin.conf
new file mode 100644
index 0000000000..06cdd7e6c7
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/60-latin.conf
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+ <alias>
+ <family>serif</family>
+ <prefer>
+ <family>Bitstream Vera Serif</family>
+ <family>DejaVu Serif</family>
+ <family>Times New Roman</family>
+ <family>Thorndale AMT</family>
+ <family>Luxi Serif</family>
+ <family>Nimbus Roman No9 L</family>
+ <family>Times</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>sans-serif</family>
+ <prefer>
+ <family>Bitstream Vera Sans</family>
+ <family>DejaVu Sans</family>
+ <family>Verdana</family>
+ <family>Arial</family>
+ <family>Albany AMT</family>
+ <family>Luxi Sans</family>
+ <family>Nimbus Sans L</family>
+ <family>Helvetica</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>monospace</family>
+ <prefer>
+ <family>Bitstream Vera Sans Mono</family>
+ <family>DejaVu Sans Mono</family>
+ <family>Andale Mono</family>
+ <family>Courier New</family>
+ <family>Cumberland AMT</family>
+ <family>Luxi Mono</family>
+ <family>Nimbus Mono L</family>
+ <family>Courier</family>
+ </prefer>
+ </alias>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/65-fonts-persian.conf b/system/players/dvdplayer/etc/fonts/conf.avail/65-fonts-persian.conf
new file mode 100644
index 0000000000..e30c4d9691
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/65-fonts-persian.conf
@@ -0,0 +1,539 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- /etc/fonts/conf.d/10-fonts-persian.conf -->
+<!--
+ fonts-persian.conf
+ To configure Persian fonts from The FarsiWeb Project.
+
+ Copyright (C) 2005 Sharif FarsiWeb, Inc. <license@farsiweb.info>
+
+ Permission to use, copy, modify, distribute, and sell this software and its
+ documentation for any purpose is hereby granted without fee, provided that
+ the above copyright notice appear in all copies and that both that
+ copyright notice and this permission notice appear in supporting
+ documentation, and that the name of Sharif FarsiWeb, Inc. not be used in
+ advertising or publicity pertaining to distribution of the software without
+ specific, written prior permission. Sharif FarsiWeb, Inc. makes no
+ representations about the suitability of this software for any purpose. It
+ is provided "as is" without express or implied warranty.
+
+ SHARIF FARSIWEB, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ PERFORMANCE OF THIS SOFTWARE.
+
+ ChangeLog:
+ 2005-04-03 Behdad Esfahbod: Initial revision.
+ 2005-10-09 Behdad Esfahbod: Turned off back-slant and Tahoma sections.
+ 2005-11-30 Behdad Esfahbod: Set Titr susbtitution size to 24 points.
+
+ Todo:
+ Add generic font "fantasy". Add some fonts into that category.
+ Maybe add a "cursive" generic font.
+ -->
+<fontconfig>
+
+
+<!--
+ We don't want weak bindings. So got to use the syntactical expansion
+ of alias tag to do binding=same :(. Please support that in alias.
+ -->
+
+
+<!-- Deprecated fonts are discouraged -->
+
+ <!-- Nesf[2] is officially deprecated and has problematic tables -->
+ <match>
+ <test name="family">
+ <string>Nesf</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Nesf2</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Nesf2</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Persian_sansserif_default</string>
+ </edit>
+ </match>
+
+ <!-- Tahoma looks awful (TURNED-OFF) -->
+ <!--match>
+ <test name="family">
+ <string>Tahoma</string>
+ </test>
+ <edit name="family" mode="prepend" binding="same">
+ <string>Persian_sansserif_default</string>
+ </edit>
+ </match-->
+
+<!-- Name changes and spelling variant aliases -->
+
+ <!-- Changed due to trademark problems -->
+ <match>
+ <test name="family">
+ <string>Nazanin</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Nazli</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Lotus</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Lotoos</string>
+ </edit>
+ </match>
+
+ <!-- Changed due to transcription orthography -->
+ <match>
+ <test name="family">
+ <string>Yaqut</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Yaghoot</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Yagut</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Yaghoot</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Yaghut</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Yaghoot</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Traffic</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Terafik</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Ferdowsi</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Ferdosi</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Fantezy</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Fantezi</string>
+ </edit>
+ </match>
+
+
+<!-- Classify fonts. -->
+
+ <!-- Persian_title class -->
+ <match>
+ <test name="family">
+ <string>Jadid</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_title</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Titr</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_title</string>
+ </edit>
+ </match>
+
+ <!-- Persian_fantasy class -->
+ <match>
+ <test name="family">
+ <string>Kamran</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Homa</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_fantasy</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Homa</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Kamran</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_fantasy</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Fantezi</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_fantasy</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Tabassom</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_fantasy</string>
+ </edit>
+ </match>
+
+ <!-- Persian_square class -->
+ <match>
+ <test name="family">
+ <string>Arshia</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_square</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Nasim</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_square</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Elham</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Farnaz</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_square</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Farnaz</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Elham</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_square</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Sina</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_square</string>
+ </edit>
+ </match>
+
+<!-- Font ordering per class -->
+
+ <!-- Persian_title class -->
+ <match>
+ <test name="family">
+ <string>Persian_title</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_serif</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Jadid</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Titr</string>
+ </edit>
+ </match>
+
+ <!-- Persian_fantasy class -->
+ <match>
+ <test name="family">
+ <string>Persian_fantasy</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_square</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Tabassom</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Fantezi</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Kamran</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Homa</string>
+ </edit>
+ </match>
+
+ <!-- Persian_square class -->
+ <match>
+ <test name="family">
+ <string>Persian_square</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_serif</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Sina</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Nasim</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Farnaz</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Elham</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Arshia</string>
+ </edit>
+ </match>
+
+<!-- Register the fonts that we actually do have -->
+
+ <match target="font">
+ <test name="family">
+ <string>Elham</string>
+ </test>
+ <edit name="foundry">
+ <string>farsiweb</string>
+ </edit>
+ </match>
+
+ <match target="font">
+ <test name="family">
+ <string>Homa</string>
+ </test>
+ <edit name="foundry">
+ <string>farsiweb</string>
+ </edit>
+ </match>
+
+ <match target="font">
+ <test name="family">
+ <string>Koodak</string>
+ </test>
+ <edit name="foundry">
+ <string>farsiweb</string>
+ </edit>
+ </match>
+
+ <match target="font">
+ <test name="family">
+ <string>Nazli</string>
+ </test>
+ <edit name="foundry">
+ <string>farsiweb</string>
+ </edit>
+ </match>
+
+ <match target="font">
+ <test name="family">
+ <string>Roya</string>
+ </test>
+ <edit name="foundry">
+ <string>farsiweb</string>
+ </edit>
+ </match>
+
+ <match target="font">
+ <test name="family">
+ <string>Terafik</string>
+ </test>
+ <edit name="foundry">
+ <string>farsiweb</string>
+ </edit>
+ </match>
+
+ <match target="font">
+ <test name="family">
+ <string>Titr</string>
+ </test>
+ <edit name="foundry">
+ <string>farsiweb</string>
+ </edit>
+ </match>
+
+
+<!-- Our fonts should oblique to the other side (TURNED-OFF) -->
+
+ <match target="font">
+ <test name="foundry">
+ <!--string>farsiweb</string-->
+ <string>TURNED-OFF</string>
+ </test>
+ <test name="foundry">
+ <string>farsiweb</string>
+ </test>
+ <!-- check to see if the font is roman -->
+ <test name="slant">
+ <const>roman</const>
+ </test>
+ <!-- check to see if the pattern requested non-roman -->
+ <test target="pattern" name="slant" compare="not_eq">
+ <const>roman</const>
+ </test>
+ <!-- multiply the matrix to slant the font -->
+ <edit name="matrix" mode="assign">
+ <times>
+ <name>matrix</name>
+ <matrix><double>1</double><double>-0.2</double>
+ <double>0</double><double>1</double>
+ </matrix>
+ </times>
+ </edit>
+ <!-- pretend the font is oblique now -->
+ <edit name="slant" mode="assign">
+ <const>oblique</const>
+ </edit>
+ </match>
+
+
+<!--
+ We can't hint our fonts well, so turn off hinting.
+ Moreover, the bitmaps we have designed (well, they
+ have designed), suck, so disable them too.
+ -->
+
+ <match target="font">
+ <test name="foundry">
+ <string>farsiweb</string>
+ </test>
+ <edit name="autohint">
+ <bool>false</bool>
+ </edit>
+ <edit name="hinting">
+ <bool>false</bool>
+ </edit>
+ <edit name="embeddedbitmap">
+ <bool>false</bool>
+ </edit>
+ </match>
+
+
+<!-- Alias our fonts to common families -->
+
+ <!-- Persian serif fonts -->
+ <alias>
+ <family>serif</family>
+ <accept>
+ <family>Nazli</family>
+ <family>Lotoos</family>
+ <family>Mitra</family>
+ <family>Ferdosi</family>
+ <family>Badr</family>
+ <family>Zar</family>
+ </accept>
+ </alias>
+
+ <!-- Persian sans-serif fonts -->
+ <alias>
+ <family>sans-serif</family>
+ <accept>
+ <family>Roya</family>
+ <family>Koodak</family>
+ <family>Terafik</family>
+ </accept>
+ </alias>
+
+ <!-- Persian monospace fonts -->
+ <alias>
+ <family>monospace</family>
+ <accept>
+ <!-- Not really monospace -->
+ <family>Terafik</family>
+ </accept>
+ </alias>
+
+
+<!-- Use Titr in titles -->
+
+ <!-- Both serif... -->
+ <match>
+ <test name="family">
+ <string>serif</string>
+ </test>
+ <test name="weight" compare="more_eq">
+ <int>200</int>
+ </test>
+ <test name="size" compare="more_eq">
+ <double>24</double>
+ </test>
+ <edit name="family" mode="prepend">
+ <string>Titr</string>
+ </edit>
+ </match>
+
+ <!-- and sans-serif. -->
+ <match>
+ <test name="family">
+ <string>sans-serif</string>
+ </test>
+ <test name="weight" compare="more_eq">
+ <int>200</int>
+ </test>
+ <test name="size" compare="more_eq">
+ <double>24</double>
+ </test>
+ <edit name="family" mode="prepend">
+ <string>Titr</string>
+ </edit>
+ </match>
+
+ <!-- and more. -->
+ <match>
+ <test name="family">
+ <string>Persian_sansserif_default</string>
+ </test>
+ <test name="weight" compare="more_eq">
+ <int>200</int>
+ </test>
+ <test name="size" compare="more_eq">
+ <double>24</double>
+ </test>
+ <edit name="family" mode="prepend" binding="same">
+ <string>Titr</string>
+ </edit>
+ </match>
+
+
+<!-- Default substituted for deprecated sans-serif fonts -->
+
+ <match>
+ <test name="family">
+ <string>Persian_sansserif_default</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Roya</string>
+ </edit>
+ </match>
+
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/65-nonlatin.conf b/system/players/dvdplayer/etc/fonts/conf.avail/65-nonlatin.conf
new file mode 100644
index 0000000000..f8dbb64fc4
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/65-nonlatin.conf
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+ <alias>
+ <family>serif</family>
+ <prefer>
+ <family>Frank Ruehl</family>
+ <family>MgOpen Canonica</family>
+ <family>Kochi Mincho</family>
+ <family>AR PL SungtiL GB</family>
+ <family>AR PL Mingti2L Big5</family>
+ <family>пј­пјі жЋжњќ</family>
+ <family>Baekmuk Batang</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>sans-serif</family>
+ <prefer>
+ <family>Nachlieli</family>
+ <family>MgOpen Modata</family>
+ <family>Kochi Gothic</family>
+ <family>AR PL KaitiM GB</family>
+ <family>AR PL KaitiM Big5</family>
+ <family>пј­пјі г‚ґг‚·гѓѓг‚Ї</family>
+ <family>Baekmuk Dotum</family>
+ <family>SimSun</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>monospace</family>
+ <prefer>
+ <family>Miriam Mono</family>
+ <family>Kochi Gothic</family>
+ <family>AR PL KaitiM GB</family>
+ <family>Baekmuk Dotum</family>
+ </prefer>
+ </alias>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/69-unifont.conf b/system/players/dvdplayer/etc/fonts/conf.avail/69-unifont.conf
new file mode 100644
index 0000000000..a784af920d
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/69-unifont.conf
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+ <alias>
+ <family>serif</family>
+ <prefer>
+ <family>FreeSerif</family>
+ <family>Code2000</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>sans-serif</family>
+ <prefer>
+ <family>FreeSans</family>
+ <family>Arial Unicode MS</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>monospace</family>
+ <prefer>
+ <family>FreeMono</family>
+ </prefer>
+ </alias>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/70-no-bitmaps.conf b/system/players/dvdplayer/etc/fonts/conf.avail/70-no-bitmaps.conf
new file mode 100644
index 0000000000..e8fb6a947f
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/70-no-bitmaps.conf
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- /etc/fonts/conf.d/no-bitmaps.conf -->
+<fontconfig>
+<!-- Reject bitmap fonts -->
+ <selectfont>
+ <rejectfont>
+ <pattern>
+ <patelt name="scalable"><bool>false</bool></patelt>
+ </pattern>
+ </rejectfont>
+ </selectfont>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/70-yes-bitmaps.conf b/system/players/dvdplayer/etc/fonts/conf.avail/70-yes-bitmaps.conf
new file mode 100644
index 0000000000..c539c70ac3
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/70-yes-bitmaps.conf
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- conf.d/yes-bitmaps.conf -->
+<fontconfig>
+<!-- Accept bitmap fonts -->
+ <selectfont>
+ <acceptfont>
+ <pattern>
+ <patelt name="scalable"><bool>false</bool></patelt>
+ </pattern>
+ </acceptfont>
+ </selectfont>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/80-delicious.conf b/system/players/dvdplayer/etc/fonts/conf.avail/80-delicious.conf
new file mode 100644
index 0000000000..701429bcc4
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/80-delicious.conf
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- /etc/fonts/conf.d/60-delicious.conf -->
+<fontconfig>
+<!-- Fix-ups for Delicious family -->
+
+<!-- Delicious 'heavy' variant says its Medium weight -->
+<match target="scan">
+ <test name="family">
+ <string>Delicious</string>
+ </test>
+ <test name="style">
+ <string>Heavy</string>
+ </test>
+ <edit name="weight">
+ <const>heavy</const>
+ </edit>
+</match>
+
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/90-synthetic.conf b/system/players/dvdplayer/etc/fonts/conf.avail/90-synthetic.conf
new file mode 100644
index 0000000000..63d9b891b3
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/90-synthetic.conf
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+<!--
+ Artificial oblique for fonts without an italic or oblique version
+ -->
+
+ <match target="font">
+ <!-- check to see if the font is roman -->
+ <test name="slant">
+ <const>roman</const>
+ </test>
+ <!-- check to see if the pattern requested non-roman -->
+ <test target="pattern" name="slant" compare="not_eq">
+ <const>roman</const>
+ </test>
+ <!-- multiply the matrix to slant the font -->
+ <edit name="matrix" mode="assign">
+ <times>
+ <name>matrix</name>
+ <matrix><double>1</double><double>0.2</double>
+ <double>0</double><double>1</double>
+ </matrix>
+ </times>
+ </edit>
+ <!-- pretend the font is oblique now -->
+ <edit name="slant" mode="assign">
+ <const>oblique</const>
+ </edit>
+ <!-- and disable embedded bitmaps for artificial oblique -->
+ <edit name="embeddedbitmap" mode="assign">
+ <bool>false</bool>
+ </edit>
+ </match>
+
+<!--
+ Synthetic emboldening for fonts that do not have bold face available
+ -->
+
+ <match target="font">
+ <!-- check to see if the font is just regular -->
+ <test name="weight" compare="less_eq">
+ <const>medium</const>
+ </test>
+ <!-- check to see if the pattern requests bold -->
+ <test target="pattern" name="weight" compare="more">
+ <const>medium</const>
+ </test>
+ <!--
+ set the embolden flag
+ needed for applications using cairo, e.g. gucharmap, gedit, ...
+ -->
+ <edit name="embolden" mode="assign">
+ <bool>true</bool>
+ </edit>
+ <!--
+ set weight to bold
+ needed for applications using Xft directly, e.g. Firefox, ...
+ -->
+ <edit name="weight" mode="assign">
+ <const>bold</const>
+ </edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.avail/README b/system/players/dvdplayer/etc/fonts/conf.avail/README
new file mode 100644
index 0000000000..dbcfe2135f
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.avail/README
@@ -0,0 +1,48 @@
+conf.d/README
+
+Each file in this directory is a fontconfig configuration file. Fontconfig
+scans this directory, loading all files of the form [0-9][0-9]*. These files
+are normally installed in ../conf.avail and then symlinked here, allowing
+them to be easily installed and then enabled/disabled by adjusting the
+symlinks.
+
+The files are loaded in numeric order, the structure of the configuration
+has led to the following conventions in usage:
+
+ Files begining with: Contain:
+
+ 00 through 09 Font directories
+ 10 through 19 system rendering defaults (AA, etc)
+ 10-autohint.conf
+ 10-no-sub-pixel.conf
+ 10-sub-pixel-bgr.conf
+ 10-sub-pixel-rgb.conf
+ 10-sub-pixel-vbgr.conf
+ 10-sub-pixel-vrgb.conf
+ 10-unhinted.conf
+ 20 through 29 font rendering options
+ 20-fix-globaladvance.conf
+ 20-lohit-gujarati.conf
+ 20-unhint-small-vera.conf
+ 30 through 39 family substitution
+ 30-urw-aliases.conf
+ 30-amt-aliases.conf
+ 40 through 49 generic identification, map family->generic
+ 40-generic-id.conf
+ 49-sansserif.conf
+ 50 through 59 alternate config file loading
+ 50-user.conf Load ~/.fonts.conf
+ 51-local.conf Load local.conf
+ 60 through 69 generic aliases
+ 60-latin.conf
+ 65-fonts-persian.conf
+ 65-nonlatin.conf
+ 69-unifont.conf
+ 70 through 79 select font (adjust which fonts are available)
+ 70-no-bitmaps.conf
+ 70-yes-bitmaps.conf
+ 80 through 89 match target="scan" (modify scanned patterns)
+ 80-delicious.conf
+ 90 through 98 font synthesis
+ 90-synthetic.conf
+
diff --git a/system/players/dvdplayer/etc/fonts/conf.d/20-fix-globaladvance.conf b/system/players/dvdplayer/etc/fonts/conf.d/20-fix-globaladvance.conf
new file mode 100644
index 0000000000..a62162ca0f
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.d/20-fix-globaladvance.conf
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- conf.d/sub-pixel.conf -->
+<fontconfig>
+<!--
+ Some Asian fonts misadvertise themselves as monospaced when
+ in fact they are dual-spaced (half and full). This makes
+ FreeType very confused as it forces all widths to match.
+ Undo this magic by disabling the width forcing code -->
+ <match target="font">
+ <test name="family"><string>GulimChe</string></test>
+ <edit name="globaladvance"><bool>false</bool></edit>
+ </match>
+
+ <match target="font">
+ <test name="family"><string>DotumChe</string></test>
+ <edit name="globaladvance"><bool>false</bool></edit>
+ </match>
+
+ <match target="font">
+ <test name="family"><string>BatangChe</string></test>
+ <edit name="globaladvance"><bool>false</bool></edit>
+ </match>
+
+ <match target="font">
+ <test name="family"><string>GungsuhChe</string></test>
+ <edit name="globaladvance"><bool>false</bool></edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.d/20-lohit-gujarati.conf b/system/players/dvdplayer/etc/fonts/conf.d/20-lohit-gujarati.conf
new file mode 100644
index 0000000000..1c29d0d0ad
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.d/20-lohit-gujarati.conf
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+
+<!-- Available Gujarti fonts look much better without hinting -->
+
+ <match target="font">
+ <test name="family"><string>Lohit Gujarati</string></test>
+ <edit name="hinting"><bool>false</bool></edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.d/20-unhint-small-vera.conf b/system/players/dvdplayer/etc/fonts/conf.d/20-unhint-small-vera.conf
new file mode 100644
index 0000000000..3078119803
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.d/20-unhint-small-vera.conf
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- conf.d/sub-pixel.conf -->
+<fontconfig>
+<!--
+ The Bitstream Vera fonts have GASP entries suggesting that hinting be
+ disabled below 8 ppem, but FreeType ignores those, preferring to use
+ the data found in the instructed hints. The initial Vera release
+ didn't include the right instructions in the 'prep' table. Fix this
+ by disabling hinting manually at smaller sizes (< 8ppem)
+ -->
+
+ <match target="font">
+ <test name="family">
+ <string>Bitstream Vera Sans</string>
+ </test>
+ <test name="pixelsize" compare="less">
+ <double>7.5</double>
+ </test>
+ <edit name="hinting">
+ <bool>false</bool>
+ </edit>
+ </match>
+
+ <match target="font">
+ <test name="family">
+ <string>Bitstream Vera Serif</string>
+ </test>
+ <test name="pixelsize" compare="less">
+ <double>7.5</double>
+ </test>
+ <edit name="hinting">
+ <bool>false</bool>
+ </edit>
+ </match>
+
+ <match target="font">
+ <test name="family">
+ <string>Bitstream Vera Sans Mono</string>
+ </test>
+ <test name="pixelsize" compare="less">
+ <double>7.5</double>
+ </test>
+ <edit name="hinting">
+ <bool>false</bool>
+ </edit>
+ </match>
+
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.d/30-amt-aliases.conf b/system/players/dvdplayer/etc/fonts/conf.d/30-amt-aliases.conf
new file mode 100644
index 0000000000..d6df67e055
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.d/30-amt-aliases.conf
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- conf.d/sub-pixel.conf -->
+<fontconfig>
+<!--
+ AMT provides metric and shape compatible fonts for these three web font
+ families.
+ -->
+ <alias>
+ <family>Times New Roman</family>
+ <accept><family>Thorndale AMT</family></accept>
+ </alias>
+ <alias>
+ <family>Arial</family>
+ <accept><family>Albany AMT</family></accept>
+ </alias>
+ <alias>
+ <family>Courier New</family>
+ <accept><family>Cumberland AMT</family></accept>
+ </alias>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.d/30-urw-aliases.conf b/system/players/dvdplayer/etc/fonts/conf.d/30-urw-aliases.conf
new file mode 100644
index 0000000000..cf90dd5466
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.d/30-urw-aliases.conf
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- conf.d/sub-pixel.conf -->
+<fontconfig>
+<!--
+ URW provides metric and shape compatible fonts for these 10 Adobe families.
+ -->
+ <alias>
+ <family>Avant Garde</family>
+ <accept><family>URW Gothic L</family></accept>
+ </alias>
+ <alias>
+ <family>Bookman</family>
+ <accept><family>URW Bookman L</family></accept>
+ </alias>
+ <alias>
+ <family>Courier</family>
+ <accept><family>Nimbus Mono L</family></accept>
+ </alias>
+ <alias>
+ <family>Helvetica</family>
+ <accept><family>Nimbus Sans L</family></accept>
+ </alias>
+ <alias>
+ <family>New Century Schoolbook</family>
+ <accept><family>Century Schoolbook L</family></accept>
+ </alias>
+ <alias>
+ <family>Palatino</family>
+ <accept><family>URW Palladio L</family></accept>
+ </alias>
+ <alias>
+ <family>Times</family>
+ <accept><family>Nimbus Roman No9 L</family></accept>
+ </alias>
+ <alias>
+ <family>Zapf Chancery</family>
+ <accept><family>URW Chancery L</family></accept>
+ </alias>
+ <alias>
+ <family>Zapf Dingbats</family>
+ <accept><family>Dingbats</family></accept>
+ </alias>
+ <match target="pattern">
+ <test name="family">
+ <string>Symbol</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Standard Symbols L</string>
+ </edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.d/40-generic.conf b/system/players/dvdplayer/etc/fonts/conf.d/40-generic.conf
new file mode 100644
index 0000000000..84e85e44bb
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.d/40-generic.conf
@@ -0,0 +1,66 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+<!--
+ Mark common families with their generics so we'll get
+ something reasonable
+-->
+
+<!--
+ Serif faces
+ -->
+ <alias>
+ <family>Bitstream Vera Serif</family>
+ <family>DejaVu Serif</family>
+ <family>Times New Roman</family>
+ <family>Times</family>
+ <family>Nimbus Roman No9 L</family>
+ <family>Luxi Serif</family>
+ <family>Kochi Mincho</family>
+ <family>AR PL SungtiL GB</family>
+ <family>AR PL Mingti2L Big5</family>
+ <family>пј­пјі жЋжњќ</family>
+ <family>Baekmuk Batang</family>
+ <family>FreeSerif</family>
+ <family>MgOpen Canonica</family>
+ <default><family>serif</family></default>
+ </alias>
+<!--
+ Sans-serif faces
+ -->
+ <alias>
+ <family>Bitstream Vera Sans</family>
+ <family>DejaVu Sans</family>
+ <family>Helvetica</family>
+ <family>Arial</family>
+ <family>Verdana</family>
+ <family>Albany AMT</family>
+ <family>Nimbus Sans L</family>
+ <family>Luxi Sans</family>
+ <family>Kochi Gothic</family>
+ <family>AR PL KaitiM GB</family>
+ <family>AR PL KaitiM Big5</family>
+ <family>пј­пјі г‚ґг‚·гѓѓг‚Ї</family>
+ <family>Baekmuk Dotum</family>
+ <family>SimSun</family>
+ <family>FreeSans</family>
+ <family>MgOpen Modata</family>
+ <default><family>sans-serif</family></default>
+ </alias>
+<!--
+ Monospace faces
+ -->
+ <alias>
+ <family>Bitstream Vera Sans Mono</family>
+ <family>DejaVu Sans Mono</family>
+ <family>Courier</family>
+ <family>Courier New</family>
+ <family>Andale Mono</family>
+ <family>Luxi Mono</family>
+ <family>Cumberland AMT</family>
+ <family>Nimbus Mono L</family>
+ <family>NSimSun</family>
+ <family>FreeMono</family>
+ <default><family>monospace</family></default>
+ </alias>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.d/49-sansserif.conf b/system/players/dvdplayer/etc/fonts/conf.d/49-sansserif.conf
new file mode 100644
index 0000000000..c6209a7d31
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.d/49-sansserif.conf
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+<!--
+ If the font still has no generic name, add sans-serif
+ -->
+ <match target="pattern">
+ <test qual="all" name="family" compare="not_eq">
+ <string>sans-serif</string>
+ </test>
+ <test qual="all" name="family" compare="not_eq">
+ <string>serif</string>
+ </test>
+ <test qual="all" name="family" compare="not_eq">
+ <string>monospace</string>
+ </test>
+ <edit name="family" mode="append_last">
+ <string>sans-serif</string>
+ </edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.d/50-user.conf b/system/players/dvdplayer/etc/fonts/conf.d/50-user.conf
new file mode 100644
index 0000000000..9a38a40ad9
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.d/50-user.conf
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- /etc/fonts/conf.avail/50-user.conf file to configure system font access -->
+<fontconfig>
+ <!-- Load per-user customization file -->
+ <include ignore_missing="yes">~/.fonts.conf</include>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.d/51-local.conf b/system/players/dvdplayer/etc/fonts/conf.d/51-local.conf
new file mode 100644
index 0000000000..d35046e78b
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.d/51-local.conf
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- /etc/fonts/conf.avail/51-local.conf file to configure system font access -->
+<fontconfig>
+ <!-- Load local system customization file -->
+ <include ignore_missing="yes">local.conf</include>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.d/60-latin.conf b/system/players/dvdplayer/etc/fonts/conf.d/60-latin.conf
new file mode 100644
index 0000000000..06cdd7e6c7
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.d/60-latin.conf
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+ <alias>
+ <family>serif</family>
+ <prefer>
+ <family>Bitstream Vera Serif</family>
+ <family>DejaVu Serif</family>
+ <family>Times New Roman</family>
+ <family>Thorndale AMT</family>
+ <family>Luxi Serif</family>
+ <family>Nimbus Roman No9 L</family>
+ <family>Times</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>sans-serif</family>
+ <prefer>
+ <family>Bitstream Vera Sans</family>
+ <family>DejaVu Sans</family>
+ <family>Verdana</family>
+ <family>Arial</family>
+ <family>Albany AMT</family>
+ <family>Luxi Sans</family>
+ <family>Nimbus Sans L</family>
+ <family>Helvetica</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>monospace</family>
+ <prefer>
+ <family>Bitstream Vera Sans Mono</family>
+ <family>DejaVu Sans Mono</family>
+ <family>Andale Mono</family>
+ <family>Courier New</family>
+ <family>Cumberland AMT</family>
+ <family>Luxi Mono</family>
+ <family>Nimbus Mono L</family>
+ <family>Courier</family>
+ </prefer>
+ </alias>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.d/65-fonts-persian.conf b/system/players/dvdplayer/etc/fonts/conf.d/65-fonts-persian.conf
new file mode 100644
index 0000000000..e30c4d9691
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.d/65-fonts-persian.conf
@@ -0,0 +1,539 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- /etc/fonts/conf.d/10-fonts-persian.conf -->
+<!--
+ fonts-persian.conf
+ To configure Persian fonts from The FarsiWeb Project.
+
+ Copyright (C) 2005 Sharif FarsiWeb, Inc. <license@farsiweb.info>
+
+ Permission to use, copy, modify, distribute, and sell this software and its
+ documentation for any purpose is hereby granted without fee, provided that
+ the above copyright notice appear in all copies and that both that
+ copyright notice and this permission notice appear in supporting
+ documentation, and that the name of Sharif FarsiWeb, Inc. not be used in
+ advertising or publicity pertaining to distribution of the software without
+ specific, written prior permission. Sharif FarsiWeb, Inc. makes no
+ representations about the suitability of this software for any purpose. It
+ is provided "as is" without express or implied warranty.
+
+ SHARIF FARSIWEB, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ PERFORMANCE OF THIS SOFTWARE.
+
+ ChangeLog:
+ 2005-04-03 Behdad Esfahbod: Initial revision.
+ 2005-10-09 Behdad Esfahbod: Turned off back-slant and Tahoma sections.
+ 2005-11-30 Behdad Esfahbod: Set Titr susbtitution size to 24 points.
+
+ Todo:
+ Add generic font "fantasy". Add some fonts into that category.
+ Maybe add a "cursive" generic font.
+ -->
+<fontconfig>
+
+
+<!--
+ We don't want weak bindings. So got to use the syntactical expansion
+ of alias tag to do binding=same :(. Please support that in alias.
+ -->
+
+
+<!-- Deprecated fonts are discouraged -->
+
+ <!-- Nesf[2] is officially deprecated and has problematic tables -->
+ <match>
+ <test name="family">
+ <string>Nesf</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Nesf2</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Nesf2</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Persian_sansserif_default</string>
+ </edit>
+ </match>
+
+ <!-- Tahoma looks awful (TURNED-OFF) -->
+ <!--match>
+ <test name="family">
+ <string>Tahoma</string>
+ </test>
+ <edit name="family" mode="prepend" binding="same">
+ <string>Persian_sansserif_default</string>
+ </edit>
+ </match-->
+
+<!-- Name changes and spelling variant aliases -->
+
+ <!-- Changed due to trademark problems -->
+ <match>
+ <test name="family">
+ <string>Nazanin</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Nazli</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Lotus</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Lotoos</string>
+ </edit>
+ </match>
+
+ <!-- Changed due to transcription orthography -->
+ <match>
+ <test name="family">
+ <string>Yaqut</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Yaghoot</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Yagut</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Yaghoot</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Yaghut</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Yaghoot</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Traffic</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Terafik</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Ferdowsi</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Ferdosi</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Fantezy</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Fantezi</string>
+ </edit>
+ </match>
+
+
+<!-- Classify fonts. -->
+
+ <!-- Persian_title class -->
+ <match>
+ <test name="family">
+ <string>Jadid</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_title</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Titr</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_title</string>
+ </edit>
+ </match>
+
+ <!-- Persian_fantasy class -->
+ <match>
+ <test name="family">
+ <string>Kamran</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Homa</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_fantasy</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Homa</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Kamran</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_fantasy</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Fantezi</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_fantasy</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Tabassom</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_fantasy</string>
+ </edit>
+ </match>
+
+ <!-- Persian_square class -->
+ <match>
+ <test name="family">
+ <string>Arshia</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_square</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Nasim</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_square</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Elham</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Farnaz</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_square</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Farnaz</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Elham</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_square</string>
+ </edit>
+ </match>
+ <match>
+ <test name="family">
+ <string>Sina</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_square</string>
+ </edit>
+ </match>
+
+<!-- Font ordering per class -->
+
+ <!-- Persian_title class -->
+ <match>
+ <test name="family">
+ <string>Persian_title</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_serif</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Jadid</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Titr</string>
+ </edit>
+ </match>
+
+ <!-- Persian_fantasy class -->
+ <match>
+ <test name="family">
+ <string>Persian_fantasy</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_square</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Tabassom</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Fantezi</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Kamran</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Homa</string>
+ </edit>
+ </match>
+
+ <!-- Persian_square class -->
+ <match>
+ <test name="family">
+ <string>Persian_square</string>
+ </test>
+ <edit name="family" mode="append" binding="same">
+ <string>Persian_serif</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Sina</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Nasim</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Farnaz</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Elham</string>
+ </edit>
+ <edit name="family" mode="append" binding="same">
+ <string>Arshia</string>
+ </edit>
+ </match>
+
+<!-- Register the fonts that we actually do have -->
+
+ <match target="font">
+ <test name="family">
+ <string>Elham</string>
+ </test>
+ <edit name="foundry">
+ <string>farsiweb</string>
+ </edit>
+ </match>
+
+ <match target="font">
+ <test name="family">
+ <string>Homa</string>
+ </test>
+ <edit name="foundry">
+ <string>farsiweb</string>
+ </edit>
+ </match>
+
+ <match target="font">
+ <test name="family">
+ <string>Koodak</string>
+ </test>
+ <edit name="foundry">
+ <string>farsiweb</string>
+ </edit>
+ </match>
+
+ <match target="font">
+ <test name="family">
+ <string>Nazli</string>
+ </test>
+ <edit name="foundry">
+ <string>farsiweb</string>
+ </edit>
+ </match>
+
+ <match target="font">
+ <test name="family">
+ <string>Roya</string>
+ </test>
+ <edit name="foundry">
+ <string>farsiweb</string>
+ </edit>
+ </match>
+
+ <match target="font">
+ <test name="family">
+ <string>Terafik</string>
+ </test>
+ <edit name="foundry">
+ <string>farsiweb</string>
+ </edit>
+ </match>
+
+ <match target="font">
+ <test name="family">
+ <string>Titr</string>
+ </test>
+ <edit name="foundry">
+ <string>farsiweb</string>
+ </edit>
+ </match>
+
+
+<!-- Our fonts should oblique to the other side (TURNED-OFF) -->
+
+ <match target="font">
+ <test name="foundry">
+ <!--string>farsiweb</string-->
+ <string>TURNED-OFF</string>
+ </test>
+ <test name="foundry">
+ <string>farsiweb</string>
+ </test>
+ <!-- check to see if the font is roman -->
+ <test name="slant">
+ <const>roman</const>
+ </test>
+ <!-- check to see if the pattern requested non-roman -->
+ <test target="pattern" name="slant" compare="not_eq">
+ <const>roman</const>
+ </test>
+ <!-- multiply the matrix to slant the font -->
+ <edit name="matrix" mode="assign">
+ <times>
+ <name>matrix</name>
+ <matrix><double>1</double><double>-0.2</double>
+ <double>0</double><double>1</double>
+ </matrix>
+ </times>
+ </edit>
+ <!-- pretend the font is oblique now -->
+ <edit name="slant" mode="assign">
+ <const>oblique</const>
+ </edit>
+ </match>
+
+
+<!--
+ We can't hint our fonts well, so turn off hinting.
+ Moreover, the bitmaps we have designed (well, they
+ have designed), suck, so disable them too.
+ -->
+
+ <match target="font">
+ <test name="foundry">
+ <string>farsiweb</string>
+ </test>
+ <edit name="autohint">
+ <bool>false</bool>
+ </edit>
+ <edit name="hinting">
+ <bool>false</bool>
+ </edit>
+ <edit name="embeddedbitmap">
+ <bool>false</bool>
+ </edit>
+ </match>
+
+
+<!-- Alias our fonts to common families -->
+
+ <!-- Persian serif fonts -->
+ <alias>
+ <family>serif</family>
+ <accept>
+ <family>Nazli</family>
+ <family>Lotoos</family>
+ <family>Mitra</family>
+ <family>Ferdosi</family>
+ <family>Badr</family>
+ <family>Zar</family>
+ </accept>
+ </alias>
+
+ <!-- Persian sans-serif fonts -->
+ <alias>
+ <family>sans-serif</family>
+ <accept>
+ <family>Roya</family>
+ <family>Koodak</family>
+ <family>Terafik</family>
+ </accept>
+ </alias>
+
+ <!-- Persian monospace fonts -->
+ <alias>
+ <family>monospace</family>
+ <accept>
+ <!-- Not really monospace -->
+ <family>Terafik</family>
+ </accept>
+ </alias>
+
+
+<!-- Use Titr in titles -->
+
+ <!-- Both serif... -->
+ <match>
+ <test name="family">
+ <string>serif</string>
+ </test>
+ <test name="weight" compare="more_eq">
+ <int>200</int>
+ </test>
+ <test name="size" compare="more_eq">
+ <double>24</double>
+ </test>
+ <edit name="family" mode="prepend">
+ <string>Titr</string>
+ </edit>
+ </match>
+
+ <!-- and sans-serif. -->
+ <match>
+ <test name="family">
+ <string>sans-serif</string>
+ </test>
+ <test name="weight" compare="more_eq">
+ <int>200</int>
+ </test>
+ <test name="size" compare="more_eq">
+ <double>24</double>
+ </test>
+ <edit name="family" mode="prepend">
+ <string>Titr</string>
+ </edit>
+ </match>
+
+ <!-- and more. -->
+ <match>
+ <test name="family">
+ <string>Persian_sansserif_default</string>
+ </test>
+ <test name="weight" compare="more_eq">
+ <int>200</int>
+ </test>
+ <test name="size" compare="more_eq">
+ <double>24</double>
+ </test>
+ <edit name="family" mode="prepend" binding="same">
+ <string>Titr</string>
+ </edit>
+ </match>
+
+
+<!-- Default substituted for deprecated sans-serif fonts -->
+
+ <match>
+ <test name="family">
+ <string>Persian_sansserif_default</string>
+ </test>
+ <edit name="family" mode="assign" binding="same">
+ <string>Roya</string>
+ </edit>
+ </match>
+
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.d/65-nonlatin.conf b/system/players/dvdplayer/etc/fonts/conf.d/65-nonlatin.conf
new file mode 100644
index 0000000000..f8dbb64fc4
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.d/65-nonlatin.conf
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+ <alias>
+ <family>serif</family>
+ <prefer>
+ <family>Frank Ruehl</family>
+ <family>MgOpen Canonica</family>
+ <family>Kochi Mincho</family>
+ <family>AR PL SungtiL GB</family>
+ <family>AR PL Mingti2L Big5</family>
+ <family>пј­пјі жЋжњќ</family>
+ <family>Baekmuk Batang</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>sans-serif</family>
+ <prefer>
+ <family>Nachlieli</family>
+ <family>MgOpen Modata</family>
+ <family>Kochi Gothic</family>
+ <family>AR PL KaitiM GB</family>
+ <family>AR PL KaitiM Big5</family>
+ <family>пј­пјі г‚ґг‚·гѓѓг‚Ї</family>
+ <family>Baekmuk Dotum</family>
+ <family>SimSun</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>monospace</family>
+ <prefer>
+ <family>Miriam Mono</family>
+ <family>Kochi Gothic</family>
+ <family>AR PL KaitiM GB</family>
+ <family>Baekmuk Dotum</family>
+ </prefer>
+ </alias>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.d/69-unifont.conf b/system/players/dvdplayer/etc/fonts/conf.d/69-unifont.conf
new file mode 100644
index 0000000000..a784af920d
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.d/69-unifont.conf
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+ <alias>
+ <family>serif</family>
+ <prefer>
+ <family>FreeSerif</family>
+ <family>Code2000</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>sans-serif</family>
+ <prefer>
+ <family>FreeSans</family>
+ <family>Arial Unicode MS</family>
+ </prefer>
+ </alias>
+ <alias>
+ <family>monospace</family>
+ <prefer>
+ <family>FreeMono</family>
+ </prefer>
+ </alias>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.d/80-delicious.conf b/system/players/dvdplayer/etc/fonts/conf.d/80-delicious.conf
new file mode 100644
index 0000000000..701429bcc4
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.d/80-delicious.conf
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- /etc/fonts/conf.d/60-delicious.conf -->
+<fontconfig>
+<!-- Fix-ups for Delicious family -->
+
+<!-- Delicious 'heavy' variant says its Medium weight -->
+<match target="scan">
+ <test name="family">
+ <string>Delicious</string>
+ </test>
+ <test name="style">
+ <string>Heavy</string>
+ </test>
+ <edit name="weight">
+ <const>heavy</const>
+ </edit>
+</match>
+
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/conf.d/90-synthetic.conf b/system/players/dvdplayer/etc/fonts/conf.d/90-synthetic.conf
new file mode 100644
index 0000000000..63d9b891b3
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/conf.d/90-synthetic.conf
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<fontconfig>
+<!--
+ Artificial oblique for fonts without an italic or oblique version
+ -->
+
+ <match target="font">
+ <!-- check to see if the font is roman -->
+ <test name="slant">
+ <const>roman</const>
+ </test>
+ <!-- check to see if the pattern requested non-roman -->
+ <test target="pattern" name="slant" compare="not_eq">
+ <const>roman</const>
+ </test>
+ <!-- multiply the matrix to slant the font -->
+ <edit name="matrix" mode="assign">
+ <times>
+ <name>matrix</name>
+ <matrix><double>1</double><double>0.2</double>
+ <double>0</double><double>1</double>
+ </matrix>
+ </times>
+ </edit>
+ <!-- pretend the font is oblique now -->
+ <edit name="slant" mode="assign">
+ <const>oblique</const>
+ </edit>
+ <!-- and disable embedded bitmaps for artificial oblique -->
+ <edit name="embeddedbitmap" mode="assign">
+ <bool>false</bool>
+ </edit>
+ </match>
+
+<!--
+ Synthetic emboldening for fonts that do not have bold face available
+ -->
+
+ <match target="font">
+ <!-- check to see if the font is just regular -->
+ <test name="weight" compare="less_eq">
+ <const>medium</const>
+ </test>
+ <!-- check to see if the pattern requests bold -->
+ <test target="pattern" name="weight" compare="more">
+ <const>medium</const>
+ </test>
+ <!--
+ set the embolden flag
+ needed for applications using cairo, e.g. gucharmap, gedit, ...
+ -->
+ <edit name="embolden" mode="assign">
+ <bool>true</bool>
+ </edit>
+ <!--
+ set weight to bold
+ needed for applications using Xft directly, e.g. Firefox, ...
+ -->
+ <edit name="weight" mode="assign">
+ <const>bold</const>
+ </edit>
+ </match>
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/fonts.conf b/system/players/dvdplayer/etc/fonts/fonts.conf
new file mode 100644
index 0000000000..df31883246
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/fonts.conf
@@ -0,0 +1,150 @@
+<?xml version="1.0"?>
+<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
+<!-- /etc/fonts/fonts.conf file to configure system font access -->
+<fontconfig>
+
+<!--
+ DO NOT EDIT THIS FILE.
+ IT WILL BE REPLACED WHEN FONTCONFIG IS UPDATED.
+ LOCAL CHANGES BELONG IN 'local.conf'.
+
+ The intent of this standard configuration file is to be adequate for
+ most environments. If you have a reasonably normal environment and
+ have found problems with this configuration, they are probably
+ things that others will also want fixed. Please submit any
+ problems to the fontconfig bugzilla system located at fontconfig.org
+
+ Note that the normal 'make install' procedure for fontconfig is to
+ replace any existing fonts.conf file with the new version. Place
+ any local customizations in local.conf which this file references.
+
+ Keith Packard
+-->
+
+<!-- Font directory list -->
+
+ <dir>WINDOWSFONTDIR</dir>
+
+ <dir>~/.fonts</dir>
+
+<!-- Font cache directory list -->
+
+ <cachedir>WINDOWSTEMPDIR_FONTCONFIG_CACHE</cachedir>
+ <cachedir>~/.fontconfig</cachedir>
+
+<!--
+ Accept deprecated 'mono' alias, replacing it with 'monospace'
+-->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>mono</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>monospace</string>
+ </edit>
+ </match>
+
+<!--
+ Accept alternate 'sans serif' spelling, replacing it with 'sans-serif'
+-->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>sans serif</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>sans-serif</string>
+ </edit>
+ </match>
+
+<!--
+ Accept deprecated 'sans' alias, replacing it with 'sans-serif'
+-->
+ <match target="pattern">
+ <test qual="any" name="family">
+ <string>sans</string>
+ </test>
+ <edit name="family" mode="assign">
+ <string>sans-serif</string>
+ </edit>
+ </match>
+
+<!--
+ Load local system customization file
+-->
+ <include ignore_missing="yes">conf.d</include>
+
+ <config>
+<!--
+ These are the default Unicode chars that are expected to be blank
+ in fonts. All other blank chars are assumed to be broken and
+ won't appear in the resulting charsets
+ -->
+ <blank>
+ <int>0x0020</int> <!-- SPACE -->
+ <int>0x00A0</int> <!-- NO-BREAK SPACE -->
+ <int>0x00AD</int> <!-- SOFT HYPHEN -->
+ <int>0x034F</int> <!-- COMBINING GRAPHEME JOINER -->
+ <int>0x0600</int> <!-- ARABIC NUMBER SIGN -->
+ <int>0x0601</int> <!-- ARABIC SIGN SANAH -->
+ <int>0x0602</int> <!-- ARABIC FOOTNOTE MARKER -->
+ <int>0x0603</int> <!-- ARABIC SIGN SAFHA -->
+ <int>0x06DD</int> <!-- ARABIC END OF AYAH -->
+ <int>0x070F</int> <!-- SYRIAC ABBREVIATION MARK -->
+ <int>0x115F</int> <!-- HANGUL CHOSEONG FILLER -->
+ <int>0x1160</int> <!-- HANGUL JUNGSEONG FILLER -->
+ <int>0x1680</int> <!-- OGHAM SPACE MARK -->
+ <int>0x17B4</int> <!-- KHMER VOWEL INHERENT AQ -->
+ <int>0x17B5</int> <!-- KHMER VOWEL INHERENT AA -->
+ <int>0x180E</int> <!-- MONGOLIAN VOWEL SEPARATOR -->
+ <int>0x2000</int> <!-- EN QUAD -->
+ <int>0x2001</int> <!-- EM QUAD -->
+ <int>0x2002</int> <!-- EN SPACE -->
+ <int>0x2003</int> <!-- EM SPACE -->
+ <int>0x2004</int> <!-- THREE-PER-EM SPACE -->
+ <int>0x2005</int> <!-- FOUR-PER-EM SPACE -->
+ <int>0x2006</int> <!-- SIX-PER-EM SPACE -->
+ <int>0x2007</int> <!-- FIGURE SPACE -->
+ <int>0x2008</int> <!-- PUNCTUATION SPACE -->
+ <int>0x2009</int> <!-- THIN SPACE -->
+ <int>0x200A</int> <!-- HAIR SPACE -->
+ <int>0x200B</int> <!-- ZERO WIDTH SPACE -->
+ <int>0x200C</int> <!-- ZERO WIDTH NON-JOINER -->
+ <int>0x200D</int> <!-- ZERO WIDTH JOINER -->
+ <int>0x200E</int> <!-- LEFT-TO-RIGHT MARK -->
+ <int>0x200F</int> <!-- RIGHT-TO-LEFT MARK -->
+ <int>0x2028</int> <!-- LINE SEPARATOR -->
+ <int>0x2029</int> <!-- PARAGRAPH SEPARATOR -->
+ <int>0x202A</int> <!-- LEFT-TO-RIGHT EMBEDDING -->
+ <int>0x202B</int> <!-- RIGHT-TO-LEFT EMBEDDING -->
+ <int>0x202C</int> <!-- POP DIRECTIONAL FORMATTING -->
+ <int>0x202D</int> <!-- LEFT-TO-RIGHT OVERRIDE -->
+ <int>0x202E</int> <!-- RIGHT-TO-LEFT OVERRIDE -->
+ <int>0x202F</int> <!-- NARROW NO-BREAK SPACE -->
+ <int>0x205F</int> <!-- MEDIUM MATHEMATICAL SPACE -->
+ <int>0x2060</int> <!-- WORD JOINER -->
+ <int>0x2061</int> <!-- FUNCTION APPLICATION -->
+ <int>0x2062</int> <!-- INVISIBLE TIMES -->
+ <int>0x2063</int> <!-- INVISIBLE SEPARATOR -->
+ <int>0x206A</int> <!-- INHIBIT SYMMETRIC SWAPPING -->
+ <int>0x206B</int> <!-- ACTIVATE SYMMETRIC SWAPPING -->
+ <int>0x206C</int> <!-- INHIBIT ARABIC FORM SHAPING -->
+ <int>0x206D</int> <!-- ACTIVATE ARABIC FORM SHAPING -->
+ <int>0x206E</int> <!-- NATIONAL DIGIT SHAPES -->
+ <int>0x206F</int> <!-- NOMINAL DIGIT SHAPES -->
+ <int>0x3000</int> <!-- IDEOGRAPHIC SPACE -->
+ <int>0x3164</int> <!-- HANGUL FILLER -->
+ <int>0xFEFF</int> <!-- ZERO WIDTH NO-BREAK SPACE -->
+ <int>0xFFA0</int> <!-- HALFWIDTH HANGUL FILLER -->
+ <int>0xFFF9</int> <!-- INTERLINEAR ANNOTATION ANCHOR -->
+ <int>0xFFFA</int> <!-- INTERLINEAR ANNOTATION SEPARATOR -->
+ <int>0xFFFB</int> <!-- INTERLINEAR ANNOTATION TERMINATOR -->
+ </blank>
+<!--
+ Rescan configuration every 30 seconds when FcFontSetList is called
+ -->
+ <rescan>
+ <int>30</int>
+ </rescan>
+ </config>
+
+</fontconfig>
diff --git a/system/players/dvdplayer/etc/fonts/fonts.dtd b/system/players/dvdplayer/etc/fonts/fonts.dtd
new file mode 100644
index 0000000000..a5c54f9835
--- /dev/null
+++ b/system/players/dvdplayer/etc/fonts/fonts.dtd
@@ -0,0 +1,222 @@
+<!-- This is the Document Type Definition for font configuration files -->
+<!ELEMENT fontconfig (dir |
+ cache |
+ cachedir |
+ include |
+ config |
+ selectfont |
+ match |
+ alias)* >
+
+<!--
+ Add a directory that provides fonts
+-->
+<!ELEMENT dir (#PCDATA)>
+<!ATTLIST dir xml:space (default|preserve) 'preserve'>
+
+<!--
+ Define the per-user file that holds cache font information.
+
+ If the filename begins with '~', it is replaced with the users
+ home directory path.
+-->
+<!ELEMENT cache (#PCDATA)>
+<!ATTLIST cache xml:space (default|preserve) 'preserve'>
+
+<!--
+ Add a directory that is searched for font cache files.
+ These hold per-directory cache data and are searched in
+ order for each directory. When writing cache files, the first
+ directory which allows the cache file to be created is used.
+
+ A leading '~' in a directory name is replaced with the users
+ home directory path.
+-->
+<!ELEMENT cachedir (#PCDATA)>
+<!ATTLIST cachedir xml:space (default|preserve) 'preserve'>
+
+<!--
+ Reference another configuration file; note that this
+ is another complete font configuration file and not
+ just a file included by the XML parser.
+
+ Set 'ignore_missing' to 'yes' if errors are to be ignored.
+
+ If the filename begins with '~', it is replaced with the users
+ home directory path.
+-->
+<!ELEMENT include (#PCDATA)>
+<!ATTLIST include
+ ignore_missing (no|yes) "no"
+ xml:space (default|preserve) "preserve">
+
+<!--
+ Global library configuration data
+ -->
+<!ELEMENT config (blank|rescan)*>
+
+<!--
+ Specify the set of Unicode encoding values which
+ represent glyphs that are allowed to contain no
+ data. With this list, fontconfig can examine
+ fonts for broken glyphs and eliminate them from
+ the set of valid Unicode chars. This idea
+ was borrowed from Mozilla
+ -->
+<!ELEMENT blank (int)*>
+
+<!--
+ Aliases are just a special case for multiple match elements
+
+ They are syntactically equivalent to:
+
+ <match>
+ <test name="family">
+ <string value=[family]/>
+ </test>
+ <edit name="family" mode="prepend">
+ <string value=[prefer]/>
+ ...
+ </edit>
+ <edit name="family" mode="append">
+ <string value=[accept]/>
+ ...
+ </edit>
+ <edit name="family" mode="append_last">
+ <string value=[default]/>
+ ...
+ </edit>
+ </match>
+-->
+<!--
+ Periodically rescan the font configuration and
+ directories to synch internal state with filesystem
+ -->
+<!ELEMENT rescan (int)>
+
+<!--
+ Edit list of available fonts at startup/reload time
+ -->
+<!ELEMENT selectfont (rejectfont | acceptfont)* >
+
+<!ELEMENT rejectfont (glob | pattern)*>
+
+<!ELEMENT acceptfont (glob | pattern)*>
+
+<!ELEMENT glob (#PCDATA)>
+
+<!ELEMENT pattern (patelt)*>
+
+<!ENTITY % constant 'int|double|string|matrix|bool|charset|const'>
+
+<!ELEMENT patelt (%constant;)*>
+<!ATTLIST patelt
+ name CDATA #REQUIRED>
+
+<!ELEMENT alias (family*, prefer?, accept?, default?)>
+<!ELEMENT prefer (family)*>
+<!ELEMENT accept (family)*>
+<!ELEMENT default (family)*>
+<!ELEMENT family (#PCDATA)>
+<!ATTLIST family xml:space (default|preserve) 'preserve'>
+
+<!ENTITY % expr 'int|double|string|matrix|bool|charset
+ |name|const
+ |or|and|eq|not_eq|less|less_eq|more|more_eq|contains|not_contains
+ |plus|minus|times|divide|not|if|floor|ceil|round|trunc'>
+
+<!--
+ Match and edit patterns.
+
+ If 'target' is 'pattern', execute the match before selecting a font.
+ if 'target' is 'font', execute the match on the result of a font
+ selection.
+-->
+<!ELEMENT match (test*, edit*)>
+<!ATTLIST match
+ target (pattern|font|scan) "pattern">
+
+<!--
+ Match a field in a pattern
+
+ if 'qual' is 'any', then the match succeeds if any value in the field matches.
+ if 'qual' is 'all', then the match succeeds only if all values match.
+ if 'qual' is 'first', then the match succeeds only if the first value matches.
+ if 'qual' is 'not_first', then the match succeeds only if any value other than
+ the first matches.
+ For match elements with target=font, if test 'target' is 'pattern',
+ then the test is applied to the pattern used in matching rather than
+ to the resulting font.
+
+ Match elements with target=scan are applied as fonts are scanned.
+ They edit the pattern generated from the scanned font and affect
+ what the fontconfig database contains.
+-->
+<!ELEMENT test (%expr;)*>
+<!ATTLIST test
+ qual (any|all|first|not_first) "any"
+ name CDATA #REQUIRED
+ target (pattern|font|default) "default"
+ compare (eq|not_eq|less|less_eq|more|more_eq|contains|not_contains) "eq">
+
+<!--
+ Edit a field in a pattern
+
+ The enclosed values are used together to edit the list of values
+ associated with 'name'.
+
+ If 'name' matches one of those used in a test element for this match element:
+ if 'mode' is 'assign', replace the matched value.
+ if 'mode' is 'assign_replace', replace all of the values
+ if 'mode' is 'prepend', insert before the matched value
+ if 'mode' is 'append', insert after the matched value
+ if 'mode' is 'prepend_first', insert before all of the values
+ if 'mode' is 'append_last', insert after all of the values
+ If 'name' doesn't match any of those used in a test element:
+ if 'mode' is 'assign' or 'assign_replace, replace all of the values
+ if 'mode' is 'prepend' or 'prepend_first', insert before all of the values
+ if 'mode' is 'append' or 'append_last', insert after all of the values
+-->
+<!ELEMENT edit (%expr;)*>
+<!ATTLIST edit
+ name CDATA #REQUIRED
+ mode (assign|assign_replace|prepend|append|prepend_first|append_last) "assign"
+ binding (weak|strong|same) "weak">
+
+<!--
+ Elements of expressions follow
+-->
+<!ELEMENT int (#PCDATA)>
+<!ATTLIST int xml:space (default|preserve) 'preserve'>
+<!ELEMENT double (#PCDATA)>
+<!ATTLIST double xml:space (default|preserve) 'preserve'>
+<!ELEMENT string (#PCDATA)>
+<!ATTLIST string xml:space (default|preserve) 'preserve'>
+<!ELEMENT matrix (double,double,double,double)>
+<!ELEMENT bool (#PCDATA)>
+<!ELEMENT charset (#PCDATA)>
+<!ATTLIST charset xml:space (default|preserve) 'preserve'>
+<!ELEMENT name (#PCDATA)>
+<!ATTLIST name xml:space (default|preserve) 'preserve'>
+<!ELEMENT const (#PCDATA)>
+<!ATTLIST const xml:space (default|preserve) 'preserve'>
+<!ELEMENT or (%expr;)*>
+<!ELEMENT and (%expr;)*>
+<!ELEMENT eq ((%expr;), (%expr;))>
+<!ELEMENT not_eq ((%expr;), (%expr;))>
+<!ELEMENT less ((%expr;), (%expr;))>
+<!ELEMENT less_eq ((%expr;), (%expr;))>
+<!ELEMENT more ((%expr;), (%expr;))>
+<!ELEMENT more_eq ((%expr;), (%expr;))>
+<!ELEMENT contains ((%expr;), (%expr;))>
+<!ELEMENT not_contains ((%expr;), (%expr;))>
+<!ELEMENT plus (%expr;)*>
+<!ELEMENT minus (%expr;)*>
+<!ELEMENT times (%expr;)*>
+<!ELEMENT divide (%expr;)*>
+<!ELEMENT not (%expr;)>
+<!ELEMENT if ((%expr;), (%expr;), (%expr;))>
+<!ELEMENT floor (%expr;)>
+<!ELEMENT ceil (%expr;)>
+<!ELEMENT round (%expr;)>
+<!ELEMENT trunc (%expr;)>
diff --git a/system/players/dvdplayer/fontconfig_readme b/system/players/dvdplayer/fontconfig_readme
new file mode 100644
index 0000000000..c8a5fe5f8f
--- /dev/null
+++ b/system/players/dvdplayer/fontconfig_readme
@@ -0,0 +1,15 @@
+freetype6.dll, libexpat.dll and libfontconfig-1.dll are downloaded from http://www.gtk.org/download-windows.html
+
+packages are:
+
+http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/freetype-2.3.6.zip
+
+http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/fontconfig-2.4.2-tml-20071015.zip
+
+http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/expat-2.0.0.zip
+
+If you start a movie with ssa/ass subtitles the first time on your PC, fontconfig will cache some config files,
+XBMC does not react in this time ~30 sec., wait until playback starts !! -> Note this is only for the first time
+
+
+
diff --git a/system/players/dvdplayer/freetype6.dll b/system/players/dvdplayer/freetype6.dll
new file mode 100644
index 0000000000..4a4f2586ba
--- /dev/null
+++ b/system/players/dvdplayer/freetype6.dll
Binary files differ
diff --git a/system/players/dvdplayer/liba52.dll b/system/players/dvdplayer/liba52.dll
new file mode 100644
index 0000000000..d41caf30bb
--- /dev/null
+++ b/system/players/dvdplayer/liba52.dll
Binary files differ
diff --git a/system/players/dvdplayer/libass.dll b/system/players/dvdplayer/libass.dll
new file mode 100644
index 0000000000..420bc7925a
--- /dev/null
+++ b/system/players/dvdplayer/libass.dll
Binary files differ
diff --git a/system/players/dvdplayer/libdts.dll b/system/players/dvdplayer/libdts.dll
new file mode 100644
index 0000000000..6d4de18667
--- /dev/null
+++ b/system/players/dvdplayer/libdts.dll
Binary files differ
diff --git a/system/players/dvdplayer/libdvdcss-2.dll b/system/players/dvdplayer/libdvdcss-2.dll
new file mode 100644
index 0000000000..52ec9240b1
--- /dev/null
+++ b/system/players/dvdplayer/libdvdcss-2.dll
Binary files differ
diff --git a/system/players/dvdplayer/libdvdnav.dll b/system/players/dvdplayer/libdvdnav.dll
new file mode 100644
index 0000000000..9bdeada6ba
--- /dev/null
+++ b/system/players/dvdplayer/libdvdnav.dll
Binary files differ
diff --git a/system/players/dvdplayer/libexpat.dll b/system/players/dvdplayer/libexpat.dll
new file mode 100644
index 0000000000..b8b273ec45
--- /dev/null
+++ b/system/players/dvdplayer/libexpat.dll
Binary files differ
diff --git a/system/players/dvdplayer/libfaad.dll b/system/players/dvdplayer/libfaad.dll
new file mode 100644
index 0000000000..f8a7179c1b
--- /dev/null
+++ b/system/players/dvdplayer/libfaad.dll
Binary files differ
diff --git a/system/players/dvdplayer/libfontconfig-1.dll b/system/players/dvdplayer/libfontconfig-1.dll
new file mode 100644
index 0000000000..b89b2757e1
--- /dev/null
+++ b/system/players/dvdplayer/libfontconfig-1.dll
Binary files differ
diff --git a/system/players/dvdplayer/libmad.dll b/system/players/dvdplayer/libmad.dll
new file mode 100644
index 0000000000..476f38d272
--- /dev/null
+++ b/system/players/dvdplayer/libmad.dll
Binary files differ
diff --git a/system/players/dvdplayer/libmpeg2.dll b/system/players/dvdplayer/libmpeg2.dll
new file mode 100644
index 0000000000..f8a96d0846
--- /dev/null
+++ b/system/players/dvdplayer/libmpeg2.dll
Binary files differ
diff --git a/system/players/dvdplayer/postproc-51.dll b/system/players/dvdplayer/postproc-51.dll
new file mode 100644
index 0000000000..8f80bffba4
--- /dev/null
+++ b/system/players/dvdplayer/postproc-51.dll
Binary files differ
diff --git a/system/players/dvdplayer/swscale-0.6.1.dll b/system/players/dvdplayer/swscale-0.6.1.dll
new file mode 100644
index 0000000000..3654ae675e
--- /dev/null
+++ b/system/players/dvdplayer/swscale-0.6.1.dll
Binary files differ
diff --git a/system/players/paplayer/AACCodec.dll b/system/players/paplayer/AACCodec.dll
new file mode 100644
index 0000000000..b7c9c2dcac
--- /dev/null
+++ b/system/players/paplayer/AACCodec.dll
Binary files differ
diff --git a/system/players/paplayer/AC3Codec.dll b/system/players/paplayer/AC3Codec.dll
new file mode 100644
index 0000000000..350e83dc32
--- /dev/null
+++ b/system/players/paplayer/AC3Codec.dll
Binary files differ
diff --git a/system/players/paplayer/MACDll.dll b/system/players/paplayer/MACDll.dll
new file mode 100644
index 0000000000..122b8648c7
--- /dev/null
+++ b/system/players/paplayer/MACDll.dll
Binary files differ
diff --git a/system/players/paplayer/NoseFart.dll b/system/players/paplayer/NoseFart.dll
new file mode 100644
index 0000000000..10ac372a00
--- /dev/null
+++ b/system/players/paplayer/NoseFart.dll
Binary files differ
diff --git a/system/players/paplayer/SNESAPU.DLL b/system/players/paplayer/SNESAPU.DLL
new file mode 100755
index 0000000000..13b411f8c4
--- /dev/null
+++ b/system/players/paplayer/SNESAPU.DLL
Binary files differ
diff --git a/system/players/paplayer/StSoundLibrary.dll b/system/players/paplayer/StSoundLibrary.dll
new file mode 100644
index 0000000000..544d55bf0b
--- /dev/null
+++ b/system/players/paplayer/StSoundLibrary.dll
Binary files differ
diff --git a/system/players/paplayer/adpcm.dll b/system/players/paplayer/adpcm.dll
new file mode 100644
index 0000000000..8fe66f7577
--- /dev/null
+++ b/system/players/paplayer/adpcm.dll
Binary files differ
diff --git a/system/players/paplayer/adplug-i486-linux.so b/system/players/paplayer/adplug-i486-linux.so
new file mode 100755
index 0000000000..848485dbc4
--- /dev/null
+++ b/system/players/paplayer/adplug-i486-linux.so
Binary files differ
diff --git a/system/players/paplayer/adplug.dll b/system/players/paplayer/adplug.dll
new file mode 100644
index 0000000000..2871105ed4
--- /dev/null
+++ b/system/players/paplayer/adplug.dll
Binary files differ
diff --git a/system/players/paplayer/dumb.dll b/system/players/paplayer/dumb.dll
new file mode 100644
index 0000000000..98bf7c9b81
--- /dev/null
+++ b/system/players/paplayer/dumb.dll
Binary files differ
diff --git a/system/players/paplayer/ffwma.dll b/system/players/paplayer/ffwma.dll
new file mode 100644
index 0000000000..51433f467a
--- /dev/null
+++ b/system/players/paplayer/ffwma.dll
Binary files differ
diff --git a/system/players/paplayer/gensapu.dll b/system/players/paplayer/gensapu.dll
new file mode 100644
index 0000000000..149db6453f
--- /dev/null
+++ b/system/players/paplayer/gensapu.dll
Binary files differ
diff --git a/system/players/paplayer/libFLAC.dll b/system/players/paplayer/libFLAC.dll
new file mode 100644
index 0000000000..f37a8f252c
--- /dev/null
+++ b/system/players/paplayer/libFLAC.dll
Binary files differ
diff --git a/system/players/paplayer/libmpcdec.dll b/system/players/paplayer/libmpcdec.dll
new file mode 100644
index 0000000000..f24a88bf42
--- /dev/null
+++ b/system/players/paplayer/libmpcdec.dll
Binary files differ
diff --git a/system/players/paplayer/libshnplay.dll b/system/players/paplayer/libshnplay.dll
new file mode 100644
index 0000000000..81d189327b
--- /dev/null
+++ b/system/players/paplayer/libshnplay.dll
Binary files differ
diff --git a/system/players/paplayer/libsidplay2.dll b/system/players/paplayer/libsidplay2.dll
new file mode 100644
index 0000000000..cae7dc0195
--- /dev/null
+++ b/system/players/paplayer/libsidplay2.dll
Binary files differ
diff --git a/system/players/paplayer/timidity.dll b/system/players/paplayer/timidity.dll
new file mode 100644
index 0000000000..1a03bb33e8
--- /dev/null
+++ b/system/players/paplayer/timidity.dll
Binary files differ
diff --git a/system/players/paplayer/vgmstream.dll b/system/players/paplayer/vgmstream.dll
new file mode 100644
index 0000000000..1c44409e59
--- /dev/null
+++ b/system/players/paplayer/vgmstream.dll
Binary files differ
diff --git a/system/players/paplayer/vorbisfile.dll b/system/players/paplayer/vorbisfile.dll
new file mode 100644
index 0000000000..11ea32aa52
--- /dev/null
+++ b/system/players/paplayer/vorbisfile.dll
Binary files differ
diff --git a/system/players/paplayer/wavpack.dll b/system/players/paplayer/wavpack.dll
new file mode 100644
index 0000000000..66b0d72392
--- /dev/null
+++ b/system/players/paplayer/wavpack.dll
Binary files differ
diff --git a/system/players/paplayer/wma-i486-linux.so b/system/players/paplayer/wma-i486-linux.so
new file mode 100755
index 0000000000..860bd0285a
--- /dev/null
+++ b/system/players/paplayer/wma-i486-linux.so
Binary files differ
diff --git a/system/players/paplayer/xbmc_asap-i486-linux.so b/system/players/paplayer/xbmc_asap-i486-linux.so
new file mode 100755
index 0000000000..559570b63b
--- /dev/null
+++ b/system/players/paplayer/xbmc_asap-i486-linux.so
Binary files differ
diff --git a/system/players/paplayer/xbmc_asap.dll b/system/players/paplayer/xbmc_asap.dll
new file mode 100644
index 0000000000..f5081c2c3d
--- /dev/null
+++ b/system/players/paplayer/xbmc_asap.dll
Binary files differ
diff --git a/system/python/DLLs/_socket.pyd b/system/python/DLLs/_socket.pyd
new file mode 100755
index 0000000000..330876876a
--- /dev/null
+++ b/system/python/DLLs/_socket.pyd
Binary files differ
diff --git a/system/python/DLLs/_ssl.pyd b/system/python/DLLs/_ssl.pyd
new file mode 100755
index 0000000000..206953b598
--- /dev/null
+++ b/system/python/DLLs/_ssl.pyd
Binary files differ
diff --git a/system/python/DLLs/bz2.pyd b/system/python/DLLs/bz2.pyd
new file mode 100755
index 0000000000..dcf006ee61
--- /dev/null
+++ b/system/python/DLLs/bz2.pyd
Binary files differ
diff --git a/system/python/DLLs/pyexpat.pyd b/system/python/DLLs/pyexpat.pyd
new file mode 100755
index 0000000000..0132861751
--- /dev/null
+++ b/system/python/DLLs/pyexpat.pyd
Binary files differ
diff --git a/system/python/DLLs/select.pyd b/system/python/DLLs/select.pyd
new file mode 100755
index 0000000000..8a747d9e23
--- /dev/null
+++ b/system/python/DLLs/select.pyd
Binary files differ
diff --git a/system/python/DLLs/unicodedata.pyd b/system/python/DLLs/unicodedata.pyd
new file mode 100755
index 0000000000..0ca6ed0e21
--- /dev/null
+++ b/system/python/DLLs/unicodedata.pyd
Binary files differ
diff --git a/system/python/DLLs/zlib.pyd b/system/python/DLLs/zlib.pyd
new file mode 100755
index 0000000000..3066c14bc9
--- /dev/null
+++ b/system/python/DLLs/zlib.pyd
Binary files differ
diff --git a/system/python/python24.dll b/system/python/python24.dll
new file mode 100644
index 0000000000..91591b1f26
--- /dev/null
+++ b/system/python/python24.dll
Binary files differ
diff --git a/system/python/python24.zlib b/system/python/python24.zlib
new file mode 100644
index 0000000000..e1bb9c4101
--- /dev/null
+++ b/system/python/python24.zlib
Binary files differ
diff --git a/system/python/readme.txt b/system/python/readme.txt
new file mode 100644
index 0000000000..b49b242e5a
--- /dev/null
+++ b/system/python/readme.txt
@@ -0,0 +1,16 @@
+python directory structure
+
+DLLs dir:
+ Library directory used by python.
+ python exensions (.pyd) from cvs can be placed here
+
+Lib dir:
+ Library directory used by python.
+ Here can new packages or modules be installed by the user.
+
+Spyce dir:
+ Here is where the Spyce installation remains, this is only there for use with psp (python server pages)
+ on the goahead webserver.
+
+dev note:
+unicodedata.pyd is taken from a window installation, so you won't find the source in cvs for it \ No newline at end of file
diff --git a/system/python/spyce/CHANGES b/system/python/spyce/CHANGES
new file mode 100644
index 0000000000..1bb104509e
--- /dev/null
+++ b/system/python/spyce/CHANGES
@@ -0,0 +1,566 @@
+Change Log
+
+v1.3.13
+ improved performance (approx. 3x) of single-threaded print
+ exceptions in non-default modules reported like errors in script code
+ fix: mysession.spy: session depends on pool, so switched import order
+ fix: faulty session handlers thrown out on error
+ - takes care of annoying NameError: 'pool' not found
+ fix: sys.path always returned to original state, even on error
+ globals accessible via python modules
+ - applied patch contributed by: Niko Matsakis
+ iterable objects allowed within 'for' tag
+ - modified patch submitted by: Stefan Behnel
+ spyce lambdas can return values
+ updated spyceLock.py to eliminate Python FutureWarning for large constants
+ added include.spyceStr(), idea from Santtu Pajukanta
+ fix: error module performs response.clearFilters
+ - thanks to Colin Gillespie for reporting this
+ turning on spyce.DEBUG_ERROR will also display when modules start/finish
+
+v1.3.12
+ added fix to prevent reparsing of POST stream on
+ internal redirect (modified Conan Albrecht's contribution)
+ documentation updates
+ fix: parsing totally empty files threw exception
+ user request: iterate over request object
+ modified semantics of active tags
+ - singleton tags now behave like paired tags with empty bodies
+ - defined a number of flags in spyceTag to reduce level of indentation
+ in generated python code where unnecessary:
+ conditional, loops, catches, mustend
+ - see tag documentation
+ updated core tag library accordingly
+ fix: dump_handler with binary files truncating on Windows
+ fix: files with DOS linebreaks
+ fix: both <%. and <%@ can now begin a spyce directive
+ directory listings of Spyce webserver look nicer, Apache-like
+ added form active tag library
+ added PATH_INFO functionality to spyceWWW
+
+v1.3.11
+ user request: daemon webserver mode
+ fix: mod_python flush problem
+ performance: rewrote tokenizer/parser
+ - no longer using clusmy parser generator package
+ - still pure python, compilation times between 2-6x faster
+ user request: expose functionality to define spyceProcess function
+ with arbitrary parameters, and pass in parameters... helps
+ Coil framework with Spyce integration
+ fix: spyce webserver not performing path manipulations correctly
+ on Windows
+ fix: spyce.mime file not copied for .rpm and Windows installers
+
+v1.3.10
+ Default development configuration changed to:
+ Apache 2.0.40 and Python 2.2.x
+ Release testing will be performed:
+ both on Linux and Windows
+ under CGI, FastCGI and mod_python
+ Other versions of Apache and Python should continue to work, but
+ will not be tested. I am depending on user feedback to catch any
+ errant bugs under these older configurations.
+ fix: spyceWWW properly deals with directory URLs that don't end in '/'
+ fix: request.getpost1/postget1() now accept default values
+ fix: memory cache checks file permission as well as modification time
+ fix: makefile was including .pyc/.pyo files in tarball
+ fix: spyce.vim syntax highlighting for spyce lambdas
+ fix: error module should be loaded last to avoid stdout module being
+ unloaded on error, thereby causing print statements to no longer go
+ to the browser during error handling
+ fix: error module setHandler used incorrect variable name, causing
+ setHandler to fail
+ updated spyce.vim syntax file for JSP/ASP like delimeters
+ spyce.vim now included in vim distribution
+ rpm generates spyceParserTable.py
+ (allowing for different versions of python)
+ added 'no-store' and 'must-revalidate' to response.uncacheable()
+ added pageerror configuration option to modify default page-level handler
+ rpm now requires http >2.0 and python >2.2 installed
+
+v1.3.9
+ spyceWWW web server improved
+ - configuration options integrated into spyce.conf
+ - handler mechanism created
+ - defined spyce and dump handlers
+ - reads Apache format mime-type definition files
+ - .spy files ==> spyce handler; rest ==> dump handler
+ - can display directory listings
+ - configuration options added accordingly
+ - corresponding documentation changed
+ documentation restructured to explain common configuration file
+ options in the runtime section
+ fix: docs/examples/*.gif added to rpm and windows installer
+ expanded section on how to get Spyce running under IIS via CGI
+
+v1.3.8
+ user request:
+ modified request.get/post/get1/post1/env() to accept default values
+ (note: will break code that provided caseInsensitive parameter by position)
+ added request.getpost/getpost1/postget/postget1/default() methods
+ bug fixes: python 1.5 backwards compatibility issues in the following
+ online examples: gif.spy, myPortal.spy, mysession.spy
+
+v1.3.7
+ support for ASP-style delimeters -- <% %>
+ use of Bastion eliminated, due to Python deprecation
+
+v1.3.6
+ info.spy example updated to deal with implicitly loaded taglib module
+ minor documentation fix for doc-mod_include
+ quotes for the PythonPath in httpd.conf
+
+v1.3.5
+ taglib and spylambda modules loaded implicitly only when needed
+ (i.e. when tags or spyce lambdas are actually used in a given file)
+ make install made more portable; removed install -D switch
+ EOFError now handled for file-based spyce caching (strange Windows bug?)
+ improvements to automaton module
+
+v1.3.4
+ doc updates - session module
+ minor mod_python bug - filename attribute used over environment
+ fix - windows installer unable to find python executable in some cases
+
+v1.3.3
+ examples/info.spy added
+ keep track of spyce entry point, added to spyce header
+ fix - CGI fails (only on Apache2.0!) with GET info due v1.3.2 changes
+ fix - typo in core:if tag
+
+v1.3.2
+ mod_python 3.0.1 compatibility
+ - switched to sre module, despite stack limits, because
+ pre module conflicts with pcre shared object that apache uses
+ (actually, just fails on some complicate reg.exps!)
+ This implies that very, very long spyce files might fail, until
+ sre module implements a state-machine-based reg.exp engine.
+ - apacheRequest.connection.child_num mysteriously removed,
+ therefore using os.getpid() in spyceModpyRequest.getServerID()
+ spyceApache.conf tweaked (should be more compatible)
+ installHelper.py converts backslash to forward slash
+ for httpd.conf on Windows
+ switched from pre to sre module in spyceCompile.py
+ - reason: Apache 2.0.x uses different pcre library from Python
+ causing failure under mod_python
+ - pre was used over the default (sre) because sre implementation is
+ stack-based and encountered overruns... Oh, well! Don't write
+ Spyce files that blow the stack until sre is fixed.
+
+v1.3.1
+ fix - wrapped thread-unsafe yacc-like package with lock
+ renamed util module to spyceUtil.py
+ - conflict with python1.5 site-package
+ renamed cache.py, lock.py (just in case)
+ make website update script faster
+
+v1.3.0
+ active tags introduced
+ - see: http://spyce.sourceforge.net/doc-tag.html
+ - [[.taglib]] directive added
+ - taglib spyce module added
+ - compiler changes to deal with active tags
+ - tagging infrastructure (spyceTag, spyceTagPlus, spyceTagLibrary)
+ - see: spyceTags.py
+ - user-defined active tag libraries possible
+ - see: http://spyce.sourceforge.net/doc-tag_new.html
+ - core active tag library
+ see: tags/core.py
+ see: http://spyce.sourceforge.net/doc-tag_core.html
+ - tag libraries loaded from same path as modules
+ - compiler syntax checking improved
+ - check for unbalanced parens
+ - check for unbalanced active tags
+ - extensible syntax checking for active tags
+
+v1.2.10
+ bugfix - typo in spyceWWW caused threading mode startup failure
+
+v1.2.9
+ stdout.push() can now accept no file argument
+ stdout.pop() now returns captured output
+ stdout.capture() added
+ see: examples/stdout.spy and stdout module docs
+ session_user session handler added in session module
+ see: examples/mysession.spy and session module docs
+ spylambda.define() can now memoize
+ see: http://spyce.sourceforge.net/doc-mod_lambda.html
+ memoized spyce lambda syntax: [[spy! ...: ...]]
+ see: http://spyce.sourceforge.net/doc-lang_lambda.html
+ slight modification to spyce.vim syntax file
+ response.addHeader() now support replacement
+ response.timestamp(), expire(), expireRel(), lastModified()
+ and uncacheable() methods added
+ see: http://spyce.sourceforge.net/doc-mod_response.html
+ performance!
+
+v1.2.8
+ links page added
+ spyce VIM syntax file updated; deals with spyce lambdas
+ include module improvements
+ - 'vars' field added
+ - included file can return value
+ - documentation updated, specifically regarding use of 'context'
+
+v1.2.7
+ internal restructuring continues
+ - separated spyce exceptions
+ - separated spyce configuration
+ - expanded spyce API and spyceServer
+ - spyce.spyceDone now imported as spyceDone
+ simplified spyceModule
+ - renamed wrapper field, to _api
+ - old spyceModule available as spyceModulePlus
+ - all standard modules updated
+ fixed - syntax errors were not reported properly
+ file-based spyce caching, with config option
+ performance improvements
+
+v1.2.6
+ single and multi-page documentation
+ minor fixes:
+ - NoCloseOut.flush() added
+ - BufferedOutput.flush() flushes sub-stream
+ - template module pointed at new location of cache code
+
+v1.2.5
+ spyceAPI defined: module access to spyceWrapper object restricted
+ - see: http://spyce.sourceforge.net/doc-mod_new.html
+ - (in general, will be moving towards restricted execution space)
+ toc module improved; add level(), l1()...l9() methods
+ server-level debug option added to config file
+ - see: http://spyce.sourceforge.net/doc-conf_common_debug.html
+ - debug Spyce module deprecated
+ engine now supports recursive requests (include spyce from itself)
+ sys.stdout (and therefore print statements) made thread-safe
+ spyce engine supports concurrent requests
+ server-level concurrency option added to config file
+ - see: http://spyce.sourceforge.net/doc-conf_common_concurrency.html
+ - spyce webserver operates in single, forking and threading modes
+ server-level Spyce module caching
+ - replaces Spyce-level module caching
+ - caching-related code separated from wrapper
+ code compilation seperated from wrapper (spyce.spyceCode)
+ autodetect when PYTHONOPTIMIZE causes lexer/parser failure
+ minor fixes and performance tweaks
+
+v1.2.4
+ fix - new PLY parser uses reflection at runtime to read
+ documentation strings containing grammar, thus you
+ should not run Python in optimize mode, thus
+ mod_python option in spyceApache.conf changed.
+ fix - python 1.5 compatible .spy files for docs
+
+v1.2.3
+ fix - code for new tokenizer/parser made python 1.5.2 compatible
+
+v1.2.2
+ fix - PATH_INFO via CGI
+ fix - magic (#!) on first line treated as comment
+
+v1.2.1
+ complete rewrite of spyce tokenizer and parser
+ - using PLY, table-driven
+ added spyce lambdas to language
+
+v1.2.0
+ contrib section added
+ support for SPYCE_PATH environment variable
+ lots of documentation fixes
+ decided spyce was mature enough for 1.2.0
+
+v1.1.46
+ feature request: improved examples page on website
+
+v1.1.45
+ site and documentation revamp
+ refactored the spyceModule class (see spyceModule.py)
+ altered all standard modules to conform to new internal design
+ new table-of-contents (toc) module (see docs)
+ improved stdout module (see docs)
+ added push() and pop() methods
+ now loaded implicitly
+ exception tracebacks in chunks identify specific error lines
+ file globbing added to -O command-line option
+
+v1.1.44
+ module directive deprecated
+ replaced with import tag
+ import tag accepts args attribute
+ calls module init() method at location of directive
+ init() methods added to modules: session, compress
+ see: http://spyce.sourceforge.net/doc_lang_directive.html
+ http://spyce.sourceforge.net/doc_mod.html
+ http://spyce.sourceforge.net/doc_mod_compress.html
+ http://spyce.sourceforge.net/doc_mod_session.html
+ http://spyce.sourceforge.net/doc_mod_new.html
+ bugfix - modules finalized on redirect
+
+v1.1.43
+ bugfix - included files not inheriting modules properly
+ bugfix - transform module inside included file
+
+v1.1.42
+ renamed spyce.conf to spyceApache.conf
+ renamed spyceApache to spyceModpy
+ renamed run_spyceApache to run_spyceModpy (affect spyceApache.conf)
+ added server-level configuration file functionality
+ server module search path
+ modules to load at startup
+ server-level error handler
+ global server variables
+ see: docs/doc_conf_common.html
+ added response.isCancelled() function
+ see: docs/doc_mod_response.html
+ bugfix - early client disconnect caused problems under mod_python
+
+v1.1.41
+ extended HTTP response constants to conform to spec
+ extended HTML entity encoded characters to conform to spec
+ modified internal buffering semantics to allow eliminiation of special
+ case code for specific HTTP return codes (redirects) in the common path
+ performance improvements
+ convenience functions transform.html_encode() and url_encode() added
+ error module added: handles errors that occur during spyce processing
+ bugfix - HTTP return codes propagated correctly under mod_python
+
+v1.1.40
+ bugfix - spyce syntax error propagated properly
+ response headers cleared on an internal redirect
+ case insensitive request.get,post,get1,post1,file
+
+v1.1.39
+ modified how filter module injects itself into output stream
+ added response.addFilter() to allow piped functionality
+ on the output stream, modules can insert write, writeStatic,
+ writeExpr, flush and clear handlers
+ added compress module for dynamic compression functionality
+ compress module documentation
+ renamed filter module to transform (name conflict with Python builtin)
+ sys.path forced to be absolute before changing directory in CGI mode
+ bugfix - spyce path trimmed to just filename when directory changed for
+ CGI processing
+ bugfix - spyce web server closes sockets
+
+v1.1.38
+ spyce can now run as a (proxy) web server
+ spyce -l [-p port] <server root>
+
+v1.1.37
+ spyceDone exception to stop spyce processing
+ raise spyceDone, see gif.spy, fileupload.spy examples
+ response.close() deprecated
+ not needed with spyceDone functionality
+ cPickle used in session module
+ improved session serialization performance
+
+v1.1.36
+ redirect.externalRefresh now has url= in string
+ internal redirect fixed
+ bug fix - consecutive compact line removal now possible
+ examples added: hello2.spy, form.spy
+ handle ISINDEX CGI queries that have extra command-line parameters
+ Status CGI header used for spyce redirect return codes
+
+v1.1.35
+ bug - fixed cgi chdir in case of local directory
+ request - invoke spyce engine programmatically with spyce string
+ source tarball does not contain extra CVS junk
+
+v1.1.34
+ fixed apache config bug in windows installer
+
+v1.1.33
+ appended current Spyce file's directory to sys.path
+
+v1.1.32
+ minor documentation tweaks
+ names attribute added to [[.module ]] tag
+ request.__getitem__() added
+ chdir in cgi mode
+
+v1.1.31
+ windows installer improved: apache configuration and restart
+ fixed - handling of initial spaces in multi-line strings in python chunks
+
+v1.1.30
+ red page marker in docs
+ created undefined windows lock variables
+
+v1.1.29
+ documentation split up
+ rpm is now noarch
+
+v1.1.28
+ include.dump() now has binary option
+ stdout changed to binary mode on windows for cgi purposes
+ fixed session_dir handler bug on windows
+
+v1.1.27
+ fcgi implemented on windows too
+ windows installer
+
+v1.1.26
+ fixed - nasty bug with the new module behaviour
+ small improvements to documentation and examples
+ improved request.uri() function
+
+v1.1.25
+ fixed - fcgi module broke on windows
+
+v1.1.24
+ line compaction improved
+ module behaviour on include.spyce() defined
+
+v1.1.23
+ lots of changes so that: it works on Python 1.5.2 now too!
+ file-based session handler now uses pid, and file locks
+ live examples on sourceforge
+
+v1.1.22
+ fixed Python v2.1.1-related bugs.
+ improved installation process and documentation
+ rpm more likely to succeed - uses fcgi or drops back to cgi
+ no longer mod_python based by default
+
+v1.1.21 (faulty release)
+ stochastic session clean up; no more threading dependency
+ documentation: better installation notes
+ peep-hole optimizer
+
+v1.1.20 (faulty release)
+ created explicit (swappable) cache infrastructure
+ BUG ** Spyce also works on Python v2.1
+ request - request.post(),post1() works in includes
+ documentation: cheetah install, ...
+
+v1.1.19
+ filter module
+
+v1.1.18
+ fcgi support added
+ X-Spyce header added
+ documentation: how to write new modules
+
+v1.1.17
+ feature request - compaction algorithm improved
+
+v1.1.16
+ generalised session.setHandler (session handler selection mechanism)
+ gdbm, bsd db session handlers added
+
+v1.1.15
+ minor makefile and rpm script changes
+ handling of multi-line strings in python code
+ response.flush() added
+
+v1.1.14
+ wrappers to check python version
+
+v1.1.13
+ added new language construct: "Python chunks"
+
+v1.1.12
+ stdout module redirects stdout to response object
+ added writeln() to response module
+
+v1.1.11
+ fixed lots of CGI bugs:
+ reported bug - headers not sent
+ session module thread prevented script death
+ added spyce.ONE_SHOT variable
+ cookie module fixed
+ gif.spy example fixed
+ external redirect fixed
+
+v1.1.10
+ performance:
+ implemented semantic cache for spyce compilation
+ templating module performs caching
+ lots of commenting
+
+v1.1.9
+ templating module (cheetah integration)
+ documentation
+
+v1.1.8
+ automaton module
+ documentation
+
+v1.1.7
+ associative array access to session and cookie information
+ added pool module
+ documentation
+ comments emitted as tokens
+ syntax highlighting function: include.spycecode
+ documentation
+
+v1.1.6
+ dynamically loading modules
+
+v1.1.5
+ redirect module added
+
+v1.1.4
+ response.unbuffer()
+
+v1.1.3
+ support for file upload
+ request.get1(),post1()
+
+v1.1.2
+ more reliable exception location reporting
+
+v1.1.1
+ static includes
+ module search path
+
+v1.1.0
+ Implemented modules -- major rewrite.
+ Changed includes, sessions, cookies, ... everything into modules
+ Changed the generated "stub", though this is mostly under-the-covers
+ Rewrote most of the documentation
+
+v1.0.5
+ CGI support
+ Expanded install docs
+
+v1.0.4
+ Many doc updates
+ Autosession support
+ changed directives tags to use html-like attributes
+
+v1.0.3
+ Automatic session cleanup
+ Updated pilpel image
+
+v1.0.2
+ Handle 403 - Forbidden
+ Handle 404 - Not Found
+
+v1.0.1
+ Tracking original spyce code locations in generated code
+ Reporting runtime exceptions in original spyce code
+ Reporting syntax (compile) exceptions in original spyce code
+
+v1.0 - Initial release
+ Documentation
+ Added [[.nocompact]] and [[.compact]]
+ Allowed escaped \[[ and \]] in HTML
+ Added session support, with on-disk implementation
+ Realised and implemented command-line
+ Added cookies
+ Added http header calls
+ Added get and post support
+ Created request and response objects
+ Added [[.include]]
+ Added [[.funcion]] and [[./function]]
+ Create in-memory spyce cache
+ Wrote a token-based Brace Converter
+ Added [[ ]] and [[= ]]
+ Created Spyce compiler shell
+ Wrote initial mod_python "hello world" handler
+ Read up on mod_python
+ Looked at PyServ
+ Attempted to engineer a WebWare-based solution
+
diff --git a/system/python/spyce/Cookie.py b/system/python/spyce/Cookie.py
new file mode 100644
index 0000000000..c2f0281cee
--- /dev/null
+++ b/system/python/spyce/Cookie.py
@@ -0,0 +1,557 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+# Cookie.py taken from Python 2.2, and modified it to work in Python 1.5 -- RB
+
+__doc__ = 'Cookie parsing functionality'
+
+####
+# Copyright 2000 by Timothy O'Malley <timo@alum.mit.edu>
+#
+# All Rights Reserved
+#
+# Permission to use, copy, modify, and distribute this software
+# and its documentation for any purpose and without fee is hereby
+# granted, provided that the above copyright notice appear in all
+# copies and that both that copyright notice and this permission
+# notice appear in supporting documentation, and that the name of
+# Timothy O'Malley not be used in advertising or publicity
+# pertaining to distribution of the software without specific, written
+# prior permission.
+#
+# Timothy O'Malley DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS, IN NO EVENT SHALL Timothy O'Malley BE LIABLE FOR
+# ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+#
+
+import string
+from UserDict import UserDict
+
+try:
+ from cPickle import dumps, loads
+except ImportError:
+ from pickle import dumps, loads
+
+try:
+ import re
+except ImportError:
+ raise ImportError, "Cookie.py requires 're' from Python 1.5 or later"
+
+__all__ = ["CookieError","BaseCookie","SimpleCookie","SerialCookie",
+ "SmartCookie","Cookie"]
+
+#
+# Define an exception visible to External modules
+#
+class CookieError(Exception):
+ pass
+
+
+# These quoting routines conform to the RFC2109 specification, which in
+# turn references the character definitions from RFC2068. They provide
+# a two-way quoting algorithm. Any non-text character is translated
+# into a 4 character sequence: a forward-slash followed by the
+# three-digit octal equivalent of the character. Any '\' or '"' is
+# quoted with a preceeding '\' slash.
+#
+# These are taken from RFC2068 and RFC2109.
+# _LegalChars is the list of chars which don't require "'s
+# _Translator hash-table for fast quoting
+#
+
+ascii_lowercase = string.join(map(lambda c: chr(ord('a')+c), range(ord('z')-ord('a')+1)),'')
+ascii_uppercase = string.join(map(lambda c: chr(ord('A')+c), range(ord('z')-ord('a')+1)),'')
+
+_LegalChars = ascii_lowercase + ascii_uppercase + string.digits + "!#$%&'*+-.^_`|~"
+_Translator = {
+ '\000' : '\\000', '\001' : '\\001', '\002' : '\\002',
+ '\003' : '\\003', '\004' : '\\004', '\005' : '\\005',
+ '\006' : '\\006', '\007' : '\\007', '\010' : '\\010',
+ '\011' : '\\011', '\012' : '\\012', '\013' : '\\013',
+ '\014' : '\\014', '\015' : '\\015', '\016' : '\\016',
+ '\017' : '\\017', '\020' : '\\020', '\021' : '\\021',
+ '\022' : '\\022', '\023' : '\\023', '\024' : '\\024',
+ '\025' : '\\025', '\026' : '\\026', '\027' : '\\027',
+ '\030' : '\\030', '\031' : '\\031', '\032' : '\\032',
+ '\033' : '\\033', '\034' : '\\034', '\035' : '\\035',
+ '\036' : '\\036', '\037' : '\\037',
+
+ '"' : '\\"', '\\' : '\\\\',
+
+ '\177' : '\\177', '\200' : '\\200', '\201' : '\\201',
+ '\202' : '\\202', '\203' : '\\203', '\204' : '\\204',
+ '\205' : '\\205', '\206' : '\\206', '\207' : '\\207',
+ '\210' : '\\210', '\211' : '\\211', '\212' : '\\212',
+ '\213' : '\\213', '\214' : '\\214', '\215' : '\\215',
+ '\216' : '\\216', '\217' : '\\217', '\220' : '\\220',
+ '\221' : '\\221', '\222' : '\\222', '\223' : '\\223',
+ '\224' : '\\224', '\225' : '\\225', '\226' : '\\226',
+ '\227' : '\\227', '\230' : '\\230', '\231' : '\\231',
+ '\232' : '\\232', '\233' : '\\233', '\234' : '\\234',
+ '\235' : '\\235', '\236' : '\\236', '\237' : '\\237',
+ '\240' : '\\240', '\241' : '\\241', '\242' : '\\242',
+ '\243' : '\\243', '\244' : '\\244', '\245' : '\\245',
+ '\246' : '\\246', '\247' : '\\247', '\250' : '\\250',
+ '\251' : '\\251', '\252' : '\\252', '\253' : '\\253',
+ '\254' : '\\254', '\255' : '\\255', '\256' : '\\256',
+ '\257' : '\\257', '\260' : '\\260', '\261' : '\\261',
+ '\262' : '\\262', '\263' : '\\263', '\264' : '\\264',
+ '\265' : '\\265', '\266' : '\\266', '\267' : '\\267',
+ '\270' : '\\270', '\271' : '\\271', '\272' : '\\272',
+ '\273' : '\\273', '\274' : '\\274', '\275' : '\\275',
+ '\276' : '\\276', '\277' : '\\277', '\300' : '\\300',
+ '\301' : '\\301', '\302' : '\\302', '\303' : '\\303',
+ '\304' : '\\304', '\305' : '\\305', '\306' : '\\306',
+ '\307' : '\\307', '\310' : '\\310', '\311' : '\\311',
+ '\312' : '\\312', '\313' : '\\313', '\314' : '\\314',
+ '\315' : '\\315', '\316' : '\\316', '\317' : '\\317',
+ '\320' : '\\320', '\321' : '\\321', '\322' : '\\322',
+ '\323' : '\\323', '\324' : '\\324', '\325' : '\\325',
+ '\326' : '\\326', '\327' : '\\327', '\330' : '\\330',
+ '\331' : '\\331', '\332' : '\\332', '\333' : '\\333',
+ '\334' : '\\334', '\335' : '\\335', '\336' : '\\336',
+ '\337' : '\\337', '\340' : '\\340', '\341' : '\\341',
+ '\342' : '\\342', '\343' : '\\343', '\344' : '\\344',
+ '\345' : '\\345', '\346' : '\\346', '\347' : '\\347',
+ '\350' : '\\350', '\351' : '\\351', '\352' : '\\352',
+ '\353' : '\\353', '\354' : '\\354', '\355' : '\\355',
+ '\356' : '\\356', '\357' : '\\357', '\360' : '\\360',
+ '\361' : '\\361', '\362' : '\\362', '\363' : '\\363',
+ '\364' : '\\364', '\365' : '\\365', '\366' : '\\366',
+ '\367' : '\\367', '\370' : '\\370', '\371' : '\\371',
+ '\372' : '\\372', '\373' : '\\373', '\374' : '\\374',
+ '\375' : '\\375', '\376' : '\\376', '\377' : '\\377'
+ }
+
+def _quote(str, LegalChars=_LegalChars,
+ join=string.join, idmap=string._idmap, translate=string.translate):
+ #
+ # If the string does not need to be double-quoted,
+ # then just return the string. Otherwise, surround
+ # the string in doublequotes and precede quote (with a \)
+ # special characters.
+ #
+ if "" == translate(str, idmap, LegalChars):
+ return str
+ else:
+ return '"' + join( map(_Translator.get, str, str), "" ) + '"'
+# end _quote
+
+
+_OctalPatt = re.compile(r"\\[0-3][0-7][0-7]")
+_QuotePatt = re.compile(r"[\\].")
+
+def _unquote(str, join=string.join, atoi=string.atoi):
+ # If there aren't any doublequotes,
+ # then there can't be any special characters. See RFC 2109.
+ if len(str) < 2:
+ return str
+ if str[0] != '"' or str[-1] != '"':
+ return str
+
+ # We have to assume that we must decode this string.
+ # Down to work.
+
+ # Remove the "s
+ str = str[1:-1]
+
+ # Check for special sequences. Examples:
+ # \012 --> \n
+ # \" --> "
+ #
+ i = 0
+ n = len(str)
+ res = []
+ while 0 <= i < n:
+ Omatch = _OctalPatt.search(str, i)
+ Qmatch = _QuotePatt.search(str, i)
+ if not Omatch and not Qmatch: # Neither matched
+ res.append(str[i:])
+ break
+ # else:
+ j = k = -1
+ if Omatch: j = Omatch.start(0)
+ if Qmatch: k = Qmatch.start(0)
+ if Qmatch and ( not Omatch or k < j ): # QuotePatt matched
+ res.append(str[i:k])
+ res.append(str[k+1])
+ i = k+2
+ else: # OctalPatt matched
+ res.append(str[i:j])
+ res.append( chr( atoi(str[j+1:j+4], 8) ) )
+ i = j+4
+ return join(res, "")
+# end _unquote
+
+# The _getdate() routine is used to set the expiration time in
+# the cookie's HTTP header. By default, _getdate() returns the
+# current time in the appropriate "expires" format for a
+# Set-Cookie header. The one optional argument is an offset from
+# now, in seconds. For example, an offset of -3600 means "one hour ago".
+# The offset may be a floating point number.
+#
+
+_weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
+
+_monthname = [None,
+ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+
+def _getdate(future=0, weekdayname=_weekdayname, monthname=_monthname):
+ from time import gmtime, time
+ now = time()
+ year, month, day, hh, mm, ss, wd, y, z = gmtime(now + future)
+ return "%s, %02d-%3s-%4d %02d:%02d:%02d GMT" % \
+ (weekdayname[wd], day, monthname[month], year, hh, mm, ss)
+
+
+#
+# A class to hold ONE key,value pair.
+# In a cookie, each such pair may have several attributes.
+# so this class is used to keep the attributes associated
+# with the appropriate key,value pair.
+# This class also includes a coded_value attribute, which
+# is used to hold the network representation of the
+# value. This is most useful when Python objects are
+# pickled for network transit.
+#
+
+class Morsel(UserDict):
+ # RFC 2109 lists these attributes as reserved:
+ # path comment domain
+ # max-age secure version
+ #
+ # For historical reasons, these attributes are also reserved:
+ # expires
+ #
+ # This dictionary provides a mapping from the lowercase
+ # variant on the left to the appropriate traditional
+ # formatting on the right.
+ _reserved = { "expires" : "expires",
+ "path" : "Path",
+ "comment" : "Comment",
+ "domain" : "Domain",
+ "max-age" : "Max-Age",
+ "secure" : "secure",
+ "version" : "Version",
+ }
+ _reserved_keys = _reserved.keys()
+
+ def __init__(self):
+ # Set defaults
+ self.key = self.value = self.coded_value = None
+ UserDict.__init__(self)
+
+ # Set default attributes
+ for K in self._reserved_keys:
+ UserDict.__setitem__(self, K, "")
+ # end __init__
+
+ def __setitem__(self, K, V):
+ K = string.lower(K)
+ if not K in self._reserved_keys:
+ raise CookieError("Invalid Attribute %s" % K)
+ UserDict.__setitem__(self, K, V)
+ # end __setitem__
+
+ def isReservedKey(self, K):
+ return string.lower(K) in self._reserved_keys
+ # end isReservedKey
+
+ def set(self, key, val, coded_val,
+ LegalChars=_LegalChars,
+ idmap=string._idmap, translate=string.translate ):
+ # First we verify that the key isn't a reserved word
+ # Second we make sure it only contains legal characters
+ if string.lower(key) in self._reserved_keys:
+ raise CookieError("Attempt to set a reserved key: %s" % key)
+ if "" != translate(key, idmap, LegalChars):
+ raise CookieError("Illegal key value: %s" % key)
+
+ # It's a good key, so save it.
+ self.key = key
+ self.value = val
+ self.coded_value = coded_val
+ # end set
+
+ def output(self, attrs=None, header = "Set-Cookie:"):
+ return "%s %s" % ( header, self.OutputString(attrs) )
+
+ __str__ = output
+
+ def __repr__(self):
+ return '<%s: %s=%s>' % (self.__class__.__name__,
+ self.key, repr(self.value) )
+
+ def js_output(self, attrs=None):
+ # Print javascript
+ return """
+ <SCRIPT LANGUAGE="JavaScript">
+ <!-- begin hiding
+ document.cookie = \"%s\"
+ // end hiding -->
+ </script>
+ """ % ( self.OutputString(attrs), )
+ # end js_output()
+
+ def OutputString(self, attrs=None):
+ # Build up our result
+ #
+ result = []
+ RA = result.append
+
+ # First, the key=value pair
+ RA("%s=%s;" % (self.key, self.coded_value))
+
+ # Now add any defined attributes
+ if attrs is None:
+ attrs = self._reserved_keys
+ items = self.items()
+ items.sort()
+ for K,V in items:
+ if V == "": continue
+ if K not in attrs: continue
+ if K == "expires" and type(V) == type(1):
+ RA("%s=%s;" % (self._reserved[K], _getdate(V)))
+ elif K == "max-age" and type(V) == type(1):
+ RA("%s=%d;" % (self._reserved[K], V))
+ elif K == "secure":
+ RA("%s;" % self._reserved[K])
+ else:
+ RA("%s=%s;" % (self._reserved[K], V))
+
+ # Return the result
+ return string.join(result, " ")
+ # end OutputString
+# end Morsel class
+
+
+
+#
+# Pattern for finding cookie
+#
+# This used to be strict parsing based on the RFC2109 and RFC2068
+# specifications. I have since discovered that MSIE 3.0x doesn't
+# follow the character rules outlined in those specs. As a
+# result, the parsing rules here are less strict.
+#
+
+_LegalCharsPatt = r"[\w\d!#%&'~_`><@,:/\$\*\+\-\.\^\|\)\(\?\}\{\=]"
+_CookiePattern = re.compile(
+ r"(?x)" # This is a Verbose pattern
+ r"(?P<key>" # Start of group 'key'
+ ""+ _LegalCharsPatt +"+?" # Any word of at least one letter, nongreedy
+ r")" # End of group 'key'
+ r"\s*=\s*" # Equal Sign
+ r"(?P<val>" # Start of group 'val'
+ r'"(?:[^\\"]|\\.)*"' # Any doublequoted string
+ r"|" # or
+ ""+ _LegalCharsPatt +"*" # Any word or empty string
+ r")" # End of group 'val'
+ r"\s*;?" # Probably ending in a semi-colon
+ )
+
+
+# At long last, here is the cookie class.
+# Using this class is almost just like using a dictionary.
+# See this module's docstring for example usage.
+#
+class BaseCookie(UserDict):
+ # A container class for a set of Morsels
+ #
+
+ def value_decode(self, val):
+ """real_value, coded_value = value_decode(STRING)
+ Called prior to setting a cookie's value from the network
+ representation. The VALUE is the value read from HTTP
+ header.
+ Override this function to modify the behavior of cookies.
+ """
+ return val, val
+ # end value_encode
+
+ def value_encode(self, val):
+ """real_value, coded_value = value_encode(VALUE)
+ Called prior to setting a cookie's value from the dictionary
+ representation. The VALUE is the value being assigned.
+ Override this function to modify the behavior of cookies.
+ """
+ strval = str(val)
+ return strval, strval
+ # end value_encode
+
+ def __init__(self, input=None):
+ UserDict.__init__(self)
+ if input: self.load(input)
+ # end __init__
+
+ def __set(self, key, real_value, coded_value):
+ """Private method for setting a cookie's value"""
+ M = self.get(key, Morsel())
+ M.set(key, real_value, coded_value)
+ UserDict.__setitem__(self, key, M)
+ # end __set
+
+ def __setitem__(self, key, value):
+ """Dictionary style assignment."""
+ rval, cval = self.value_encode(value)
+ self.__set(key, rval, cval)
+ # end __setitem__
+
+ def output(self, attrs=None, header="Set-Cookie:", sep="\n"):
+ """Return a string suitable for HTTP."""
+ result = []
+ items = self.items()
+ items.sort()
+ for K,V in items:
+ result.append( V.output(attrs, header) )
+ return string.join(result, sep)
+ # end output
+
+ __str__ = output
+
+ def __repr__(self):
+ L = []
+ items = self.items()
+ items.sort()
+ for K,V in items:
+ L.append( '%s=%s' % (K,repr(V.value) ) )
+ return '<%s: %s>' % (self.__class__.__name__, string.join(L))
+
+ def js_output(self, attrs=None):
+ """Return a string suitable for JavaScript."""
+ result = []
+ items = self.items()
+ items.sort()
+ for K,V in items:
+ result.append( V.js_output(attrs) )
+ return string.join(result, "")
+ # end js_output
+
+ def load(self, rawdata):
+ """Load cookies from a string (presumably HTTP_COOKIE) or
+ from a dictionary. Loading cookies from a dictionary 'd'
+ is equivalent to calling:
+ map(Cookie.__setitem__, d.keys(), d.values())
+ """
+ if type(rawdata) == type(""):
+ self.__ParseString(rawdata)
+ else:
+ self.update(rawdata)
+ return
+ # end load()
+
+ def __ParseString(self, str, patt=_CookiePattern):
+ i = 0 # Our starting point
+ n = len(str) # Length of string
+ M = None # current morsel
+
+ while 0 <= i < n:
+ # Start looking for a cookie
+ match = patt.search(str, i)
+ if not match: break # No more cookies
+
+ K,V = match.group("key"), match.group("val")
+ i = match.end(0)
+
+ # Parse the key, value in case it's metainfo
+ if K[0] == "$":
+ # We ignore attributes which pertain to the cookie
+ # mechanism as a whole. See RFC 2109.
+ # (Does anyone care?)
+ if M:
+ M[ K[1:] ] = V
+ elif string.lower(K) in Morsel._reserved_keys:
+ if M:
+ M[ K ] = _unquote(V)
+ else:
+ rval, cval = self.value_decode(V)
+ self.__set(K, rval, cval)
+ M = self[K]
+ # end __ParseString
+# end BaseCookie class
+
+class SimpleCookie(BaseCookie):
+ """SimpleCookie
+ SimpleCookie supports strings as cookie values. When setting
+ the value using the dictionary assignment notation, SimpleCookie
+ calls the builtin str() to convert the value to a string. Values
+ received from HTTP are kept as strings.
+ """
+ def value_decode(self, val):
+ return _unquote( val ), val
+ def value_encode(self, val):
+ strval = str(val)
+ return strval, _quote( strval )
+# end SimpleCookie
+
+class SerialCookie(BaseCookie):
+ """SerialCookie
+ SerialCookie supports arbitrary objects as cookie values. All
+ values are serialized (using cPickle) before being sent to the
+ client. All incoming values are assumed to be valid Pickle
+ representations. IF AN INCOMING VALUE IS NOT IN A VALID PICKLE
+ FORMAT, THEN AN EXCEPTION WILL BE RAISED.
+
+ Note: Large cookie values add overhead because they must be
+ retransmitted on every HTTP transaction.
+
+ Note: HTTP has a 2k limit on the size of a cookie. This class
+ does not check for this limit, so be careful!!!
+ """
+ def value_decode(self, val):
+ # This could raise an exception!
+ return loads( _unquote(val) ), val
+ def value_encode(self, val):
+ return val, _quote( dumps(val) )
+# end SerialCookie
+
+class SmartCookie(BaseCookie):
+ """SmartCookie
+ SmartCookie supports arbitrary objects as cookie values. If the
+ object is a string, then it is quoted. If the object is not a
+ string, however, then SmartCookie will use cPickle to serialize
+ the object into a string representation.
+
+ Note: Large cookie values add overhead because they must be
+ retransmitted on every HTTP transaction.
+
+ Note: HTTP has a 2k limit on the size of a cookie. This class
+ does not check for this limit, so be careful!!!
+ """
+ def value_decode(self, val):
+ strval = _unquote(val)
+ try:
+ return loads(strval), val
+ except:
+ return strval, val
+ def value_encode(self, val):
+ if type(val) == type(""):
+ return val, _quote(val)
+ else:
+ return val, _quote( dumps(val) )
+# end SmartCookie
+
+
+###########################################################
+# Backwards Compatibility: Don't break any existing code!
+
+# We provide Cookie() as an alias for SmartCookie()
+Cookie = SmartCookie
+
+#
+###########################################################
+
+#Local Variables:
+#tab-width: 4
+#end:
diff --git a/system/python/spyce/LICENCE b/system/python/spyce/LICENCE
new file mode 100644
index 0000000000..4bd60a0d8e
--- /dev/null
+++ b/system/python/spyce/LICENCE
@@ -0,0 +1,40 @@
+Copyright (c) 2002-03 Rimon Barr.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice and
+this LICENCE in its entirety including the disclaimer. The LICENCE of this
+product may only be modified by the Copyright holder.
+
+2. Redistributions in binary form must reproduce the above copyright notice
+and this LICENCE in its entirety including the disclaimer in the documentation
+and/or other materials provided with the distribution.
+
+3. The end-user documentation included with the redistribution, if any, must
+include the following acknowledgment: "This product uses Spyce, Copyright
+Rimon Barr." Alternately, this acknowledgment may appear in the software
+itself, wherever such third-party acknowledgments normally appear. The
+documentation must also provide a instructions on how to receive an original
+Spyce distribution, preferably a link to the website
+http://spyce.sourceforge.net.
+
+4. The names "Spyce", or "Rimon Barr" must not be used to endorse or promote
+products derived from this software without prior written permission. For
+written permission, please contact rimon-AT-acm.org.
+
+5. Products derived from this software may not be called "Spyce", nor may
+"Spyce" appear in their names, without prior written permission of the
+Copyright holder.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RIMON BARR
+OR HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
diff --git a/system/python/spyce/README b/system/python/spyce/README
new file mode 100644
index 0000000000..1e52701737
--- /dev/null
+++ b/system/python/spyce/README
@@ -0,0 +1,15 @@
+SPYCE - Python Server Pages
+Copyright 2002-03. Rimon Barr <rimon AT acm DOT org>
+---------------------------------------------------------------------
+
+Description: Python-based dynamic HTML scripting engine.
+
+Name: SPYCE - Python Server Pages
+Author: Rimon Barr <rimon AT acm DOT org>
+
+Please refer to the LICENCE file
+
+For system documentation:
+ Run "make docs"
+ Browse the "docs/index.html" file
+
diff --git a/system/python/spyce/RELEASE b/system/python/spyce/RELEASE
new file mode 100644
index 0000000000..abf32fb70e
--- /dev/null
+++ b/system/python/spyce/RELEASE
@@ -0,0 +1,21 @@
+To release a new version of spyce:
+
+- Run: make clean
+- Edit spyce.py: change version (possibly release)
+- Edit CHANGES
+- Run: cvs update; cvs commit
+- Perform release testing
+- Run: make upload (and do the sourceforge file release)
+- Run: make sf
+- Run: make clean
+- post to freshmeat
+ spyce-users@sourceforge.net
+ python-announce@python.org
+ python-list@python.org
+ python-web-modules@yahoogroups.com
+ cheetahtemplate-discuss@lists.sourceforge.net
+ ? mod_python@modpython.org
+ ? webware-discuss@lists.sourceforge.net
+ ? sixthdev@yahoogroups.com
+ ? quixote-users@mems-exchange.org
+ ? php, jsp, apache, cherrypy
diff --git a/system/python/spyce/THANKS b/system/python/spyce/THANKS
new file mode 100644
index 0000000000..48b0b4cad2
--- /dev/null
+++ b/system/python/spyce/THANKS
@@ -0,0 +1,57 @@
+This file contains mention of people that deserve thanks.
+If you feel that you should be added, please email me
+at <rimon AT acm DOT org>
+
+Thanks (in reverse-chronological order) to:
+
+Brandon Beck <bbeck@austin.rr.com>
+ For the daemon mode suggestion
+
+Conan C. Albrecht <conan@warp.byu.edu>
+ Much help with the tags, the built-in webserver, suggestions,
+ bug reports, and fixes ...
+
+Fred Moscicki <fred@computronix.com>
+ Bug reports.
+
+Adrien Plisson <rien@yeepa.org>
+ Lots of bug reports, help with module development,
+ and input of many ideas.
+
+The NullSoft crew:
+ For NSIS SuperPiMP installer
+ http://www.nullsoft.com/free/nsis/
+
+Tino Lange <Tino.Lange@gmx.de>
+ Inspiring my work to get the Spyce engine and modules down from
+ Python 2.2 to Python 1.5.2.
+
+John J Smith <johnjsmith@rediffmail.com>
+ Finding bugs. Email discussions that led to improvements
+ in the Spyce line compacting mode, and the way modules behave
+ in included files.
+
+Piers Lauder <piers@cs.su.oz.au>
+ Email discussions that led to Python chunks (ala Poor Man's Zope),
+ filters (ala Cheetah), and some other ideas.
+
+The Cheetah team
+ http://www.cheetahtemplate.org/
+
+Natalya Katsnelson <nk74@cornell.edu>:
+ For the Spyce mascot, "Pilpel".
+
+Dave Wallace <dwallace@delanet.com>:
+ Provided initial idea in Webware's PSP implementation to add braces
+ to Python code, solving the indentation problem.
+
+Gregory Trubetskoy <grisha@modpython.org>:
+ For the mod_python project, upon which this work depends
+ http://www.modpython.org/
+
+The SourceForge team
+ http://www.sourceforge.net
+
+The Apache Team
+ http://www.apache.org/
+
diff --git a/system/python/spyce/fcgi.py b/system/python/spyce/fcgi.py
new file mode 100644
index 0000000000..d5d0f6d96d
--- /dev/null
+++ b/system/python/spyce/fcgi.py
@@ -0,0 +1,265 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+# Taken originally from: http://alldunn.com/python/fcgi.py
+# Edited a fair bit. -- RB
+
+__doc__ = 'Python Fast CGI implementation'
+
+import os, sys, string, socket, errno, cgi
+from cStringIO import StringIO
+import spyceUtil
+
+##################################################
+# Constants
+#
+
+# Protol constants: record types
+FCGI_BEGIN_REQUEST = 1
+FCGI_ABORT_REQUEST = 2
+FCGI_END_REQUEST = 3
+FCGI_PARAMS = 4
+FCGI_STDIN = 5
+FCGI_STDOUT = 6
+FCGI_STDERR = 7
+FCGI_DATA = 8
+FCGI_GET_VALUES = 9
+FCGI_GET_VALUES_RESULT = 10
+FCGI_UNKNOWN_TYPE = 11
+FCGI_MAXTYPE = FCGI_UNKNOWN_TYPE
+# Protocol constants: FCGI_BEGIN_REQUEST flag mask
+FCGI_KEEP_CONN = 1
+# Protocol constants: FCGI_BEGIN_REQUEST role
+FCGI_RESPONDER = 1
+FCGI_AUTHORIZER = 2
+FCGI_FILTER = 3
+# Protocol constants: FCGI_END_REQUEST protocolStatus
+FCGI_REQUEST_COMPLETE = 0 # ok
+FCGI_CANT_MPX_CONN = 1 # can not multiplex
+FCGI_OVERLOADED = 2 # too busy
+FCGI_UNKNOWN_ROLE = 3 # role unknown
+# Protocol constants: management record types
+FCGI_NULL_REQUEST_ID = 0
+
+# Protocol setting: maximum number of requests
+FCGI_MAX_REQS = 1
+FCGI_MAX_CONNS = 1
+# Protocol setting: can multiplex?
+FCGI_MPXS_CONNS = 0
+# Protocol setting: FastCGI protocol version
+FCGI_VERSION_1 = 1
+
+##################################################
+# Protocol
+#
+
+class record:
+ def __init__(self):
+ self.version = FCGI_VERSION_1
+ self.recType = FCGI_UNKNOWN_TYPE
+ self.reqId = FCGI_NULL_REQUEST_ID
+ self.content = ""
+ def readRecord(self, sock):
+ # read content
+ hdr = map(ord, self.readExact(sock, 8))
+ self.version = hdr[0]
+ self.recType = hdr[1]
+ self.reqId = (hdr[2]<<8)+hdr[3]
+ contentLength = (hdr[4]<<8)+hdr[5]
+ paddingLength = hdr[6]
+ self.content = self.readExact(sock, contentLength)
+ self.readExact(sock, paddingLength)
+ # parse
+ c = self.content
+ if self.recType == FCGI_BEGIN_REQUEST:
+ self.role = (ord(c[0])<<8) + ord(c[1])
+ self.flags = ord(c[2])
+ elif self.recType == FCGI_UNKNOWN_TYPE:
+ self.unknownType = ord(c[0])
+ elif self.recType == FCGI_GET_VALUES or self.recType == FCGI_PARAMS:
+ self.values={}
+ pos=0
+ while pos < len(c):
+ name, value, pos = self.decodePair(c, pos)
+ self.values[name] = value
+ elif self.recType == FCGI_END_REQUEST:
+ b = map(ord, c[0:5])
+ self.appStatus = (b[0]<<24) + (b[1]<<16) + (b[2]<<8) + b[3]
+ self.protocolStatus = b[4]
+ def writeRecord(self, sock):
+ content = self.content
+ if self.recType == FCGI_BEGIN_REQUEST:
+ content = chr(self.role>>8) + chr(self.role & 255) + chr(self.flags) + 5*'\000'
+ elif self.recType == FCGI_UNKNOWN_TYPE:
+ content = chr(self.unknownType) + 7*'\000'
+ elif self.recType==FCGI_GET_VALUES or self.recType==FCGI_PARAMS:
+ content = ""
+ for i in self.values.keys():
+ content = content + self.encodePair(i, self.values[i])
+ elif self.recType==FCGI_END_REQUEST:
+ v = self.appStatus
+ content = chr((v>>24)&255) + chr((v>>16)&255) + chr((v>>8)&255) + chr(v&255)
+ content = content + chr(self.protocolStatus) + 3*'\000'
+ cLen = len(content)
+ eLen = (cLen + 7) & (0xFFFF - 7) # align to an 8-byte boundary
+ padLen = eLen - cLen
+ hdr = [ self.version, self.recType, self.reqId >> 8,
+ self.reqId & 255, cLen >> 8, cLen & 255, padLen, 0]
+ hdr = string.joinfields(map(chr, hdr), '')
+ sock.send(hdr + content + padLen*'\000')
+ def readExact(self, sock, amount):
+ data = ''
+ while amount and len(data) < amount:
+ data = data + sock.recv(amount-len(data))
+ return data
+ def decodePair(self, s, pos):
+ nameLen=ord(s[pos]) ; pos=pos+1
+ if nameLen & 128:
+ b=map(ord, s[pos:pos+3]) ; pos=pos+3
+ nameLen=((nameLen&127)<<24) + (b[0]<<16) + (b[1]<<8) + b[2]
+ valueLen=ord(s[pos]) ; pos=pos+1
+ if valueLen & 128:
+ b=map(ord, s[pos:pos+3]) ; pos=pos+3
+ valueLen=((valueLen&127)<<24) + (b[0]<<16) + (b[1]<<8) + b[2]
+ name = s[pos:pos+nameLen] ; pos = pos + nameLen
+ value = s[pos:pos+valueLen] ; pos = pos + valueLen
+ return name, value, pos
+ def encodePair(self, name, value):
+ l=len(name)
+ if l<128: s=chr(l)
+ else: s=chr(128|(l>>24)&255)+chr((l>>16)&255)+chr((l>>8)&255)+chr(l&255)
+ l=len(value)
+ if l<128: s=s+chr(l)
+ else: s=s+chr(128|(l>>24)&255)+chr((l>>16)&255)+chr((l>>8)&255)+chr(l&255)
+ return s + name + value
+
+class FCGI:
+ def __init__(self, port=None):
+ # environment variables
+ try:
+ self.FCGI_PORT = int(os.environ['FCGI_PORT'])
+ except:
+ self.FCGI_PORT = None
+ if port: self.FCGI_PORT = port
+ self.FCGI_PORT = None
+ try:
+ self.FCGI_ALLOWED_ADDR = os.environ['FCGI_WEB_SERVER_ADDRS']
+ self.FCGI_ALLOWED_ADDR = map(string.strip, string.split(self.FCGI_ALLOWED_ADDR, ','))
+ except:
+ self.FCGI_ALLOWED_ADDR = None
+ self.firstCall = 1
+ self.clearState()
+ self.socket = None
+ self.createServerSocket()
+ def createServerSocket(self):
+ if self.FCGI_PORT:
+ s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ s.set_reuse_addr()
+ s.bind(('127.0.0.1', self.FCGI_PORT))
+ else:
+ try:
+ s=socket.fromfd(sys.stdin.fileno(), socket.AF_INET, socket.SOCK_STREAM)
+ s.getpeername()
+ except socket.error, (err, errmsg):
+ if err!=errno.ENOTCONN:
+ return
+ except:
+ return
+ self.socket = s
+ def accept(self):
+ if not self.socket: # plain CGI
+ if self.firstCall:
+ result = sys.stdin, spyceUtil.NoCloseOut(sys.stdout), sys.stderr, os.environ
+ else:
+ return 0
+ else: # FCGI
+ if not self.firstCall:
+ self.send()
+ result = self.recv()
+ self.firstCall = 0
+ return result
+ def clearState(self):
+ self.reqID = 0
+ self.connection = None
+ self.environ = {}
+ self.stdin = StringIO()
+ self.stderr = StringIO()
+ self.stdout = StringIO()
+ self.data = StringIO()
+ def send(self):
+ self.stderr.seek(0,0)
+ self.stdout.seek(0,0)
+ self.sendStream(FCGI_STDERR, self.stderr.read())
+ self.sendStream(FCGI_STDOUT, self.stdout.read())
+ r=record()
+ r.recType=FCGI_END_REQUEST
+ r.reqId=self.reqID
+ r.appStatus=0
+ r.protocolStatus=FCGI_REQUEST_COMPLETE
+ r.writeRecord(self.connection)
+ self.connection.close()
+ self.clearState()
+ def sendStream(self, streamType, streamData):
+ r=record()
+ r.recType = streamType
+ r.reqId = self.reqID
+ data = streamData
+ while data:
+ r.content, data = data[:8192], data[8192:]
+ r.writeRecord(self.connection)
+ r.content='' ; r.writeRecord(self.connection)
+ def recv(self):
+ self.connection, address = self.socket.accept()
+ # rimtodo: filter to serve only allowed addresses
+ # if good_addrs!=None and addr not in good_addrs:
+ # raise 'Connection from invalid server!'
+ remaining=1
+ while remaining:
+ r=record(); r.readRecord(self.connection)
+ if r.recType in [FCGI_GET_VALUES]: # management records
+ if r.recType == FCGI_GET_VALUES:
+ r.recType = FCGI_GET_VALUES_RESULT
+ v={}
+ vars={'FCGI_MAX_CONNS' : FCGI_MAX_CONNS,
+ 'FCGI_MAX_REQS' : FCGI_MAX_REQS,
+ 'FCGI_MPXS_CONNS': FCGI_MPXS_CONNS}
+ for i in r.values.keys():
+ if vars.has_key(i): v[i]=vars[i]
+ r.values=vars
+ r.writeRecord(self.connection)
+ elif r.reqId == 0: # management record of unknown type
+ r2 = record()
+ r2.recType = FCGI_UNKNOWN_TYPE ; r2.unknownType = r.recType
+ r2.writeRecord(self.connection)
+ continue
+ elif r.reqId != self.reqID and r.recType != FCGI_BEGIN_REQUEST:
+ continue # ignore inactive requests
+ elif r.recType == FCGI_BEGIN_REQUEST and self.reqID != 0:
+ continue # ignore BEGIN_REQUESTs in the middle of request
+ if r.recType == FCGI_BEGIN_REQUEST: # begin request
+ self.reqID = r.reqId
+ if r.role == FCGI_AUTHORIZER: remaining=1
+ elif r.role == FCGI_RESPONDER: remaining=2
+ elif r.role == FCGI_FILTER: remaining=3
+ elif r.recType == FCGI_PARAMS: # environment
+ if r.content == '': remaining=remaining-1
+ else:
+ for i in r.values.keys():
+ self.environ[i] = r.values[i]
+ elif r.recType == FCGI_STDIN: # stdin
+ if r.content == '': remaining=remaining-1
+ else: self.stdin.write(r.content)
+ elif r.recType == FCGI_DATA: # data
+ if r.content == '': remaining=remaining-1
+ else: self.data.write(r.content)
+ # end while
+ self.stdin.seek(0,0)
+ self.data.seek(0,0)
+ # return CGI environment
+ return self.stdin, spyceUtil.NoCloseOut(self.stdout), self.stderr, self.environ
+
diff --git a/system/python/spyce/installHelper.py b/system/python/spyce/installHelper.py
new file mode 100644
index 0000000000..e371fb9e2b
--- /dev/null
+++ b/system/python/spyce/installHelper.py
@@ -0,0 +1,181 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+__doc__ = 'Spyce install helper script'
+
+import os, imp, sys, getopt, string, re, time
+
+CONF_BEGIN_MARK = '### BEGIN SPYCE CONFIG MARKER'
+CONF_END_MARK = '### END SPYCE CONFIG MARKER'
+HTTPD_LOCATIONS = [
+ '/etc/httpd/conf',
+ r'C:\Program Files\Apache Group\Apache2\conf',
+ r'C:\Program Files\Apache Group\Apache\conf',
+ '/etc',
+ '/']
+APACHE_EXE_LOCATIONS = [
+ r'C:\Program Files\Apache Group\Apache2\bin',
+ r'C:\Program Files\Apache Group\Apache2',
+ r'C:\Program Files\Apache Group\Apache\bin',
+ r'C:\Program Files\Apache Group\Apache',
+]
+SYS_LOCATIONS = [
+ r'C:\winnt\system32',
+]
+
+def endsWith(s, suffix):
+ suffixLen = len(suffix)
+ return s[-suffixLen:] == suffix
+
+def listDirFilter(dir, extension):
+ files = os.listdir(dir)
+ files = filter(lambda file: endsWith(file, extension), files)
+ return files
+
+def compilePythonDir(dir):
+ print '** Compiling Python files in: %s' % dir
+ for file in listDirFilter(dir, '.py'):
+ print 'Compiling: %s' % file
+ try:
+ p = os.path.join(dir, file)
+ f = None
+ try:
+ f = open(p, 'r')
+ imp.load_source(os.path.split(file)[1][:-3], p, f)
+ finally:
+ if f: f.close()
+ except: pass
+
+def compileSpyceDir(dir):
+ import spyceCmd
+ print '** Processing Spyce files in: %s' % dir
+ for file in listDirFilter(dir, '.spy'):
+ print 'Processing: %s' % file
+ sys.argv = ['', '-o', os.path.join(dir, file[:-4]+'.html'), os.path.join(dir, file)]
+ spyceCmd.spyceMain()
+
+def findLine(array, line):
+ line = string.strip(line)
+ for i in range(len(array)):
+ if re.search(line, string.strip(array[i])):
+ return i
+ return None
+
+def unconfig(s):
+ lines = string.split(s, '\n')
+ begin = findLine(lines, CONF_BEGIN_MARK)
+ end = findLine(lines, CONF_END_MARK)
+ if begin!=None and end!=None and end>begin:
+ del lines[begin:end+1]
+ s = string.join(lines, '\n')
+ return s
+
+def config(s, root):
+ append = readFile('spyceApache.conf')
+ root = re.sub(r'\\', '/', root)
+ append = string.replace(append, 'XXX', root)
+ append = string.split(append, '\n')
+ if os.name=='nt':
+ row = findLine(append, 'ScriptInterpreterSource')
+ append[row] = string.strip(re.sub('#', '', append[row]))
+ lines = [s] + [CONF_BEGIN_MARK] + append + [CONF_END_MARK]
+ s = string.join(lines, '\n')
+ return s
+
+def readFile(filename):
+ f = None
+ try:
+ f = open(filename, 'r')
+ return f.read()
+ finally:
+ if f: f.close()
+
+def writeFileBackup(filename, new):
+ old = readFile(filename)
+ backupname = filename + '.save'
+ f = None
+ try:
+ f = open(backupname, 'w')
+ f.write(old)
+ finally:
+ if f: f.close()
+ f = None
+ try:
+ f = open(filename, 'w')
+ f.write(new)
+ finally:
+ if f: f.close()
+
+def locateFile(file, locations):
+ def visit(arg, dirname, names, file=file):
+ path = os.path.join(dirname, file)
+ if os.path.exists(path):
+ arg.append(path)
+ if arg:
+ del names[:]
+ found = []
+ for path in locations:
+ os.path.walk(path, visit, found)
+ if found:
+ return found[0]
+
+def configHTTPD(spyceroot):
+ print '** Searching for httpd.conf...'
+ file = locateFile('httpd.conf', HTTPD_LOCATIONS)
+ if file:
+ print '** Modifying httpd.conf'
+ s = readFile(file)
+ s = unconfig(s)
+ s = config(s, spyceroot)
+ writeFileBackup(file, s)
+
+def unconfigHTTPD():
+ print '** Searching for httpd.conf...'
+ file = locateFile('httpd.conf', HTTPD_LOCATIONS)
+ if file:
+ print '** Modifying httpd.conf'
+ s = readFile(file)
+ s = unconfig(s)
+ writeFileBackup(file, s)
+
+def restartApache():
+ print '** Searching for apache.exe...'
+ file = locateFile('apache.exe', APACHE_EXE_LOCATIONS)
+ cmd = locateFile('cmd.exe', SYS_LOCATIONS)
+ if file and cmd:
+ print '** Restarting Apache'
+ os.spawnl(os.P_WAIT, cmd, '/c "%s" -k restart'%file)
+ return
+ print 'Could not find apache.exe'
+
+
+
+def main():
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], '',
+ ['py=', 'spy=', 'apache=', 'apacheUN',
+ 'apacheRestart']);
+ except getopt.error:
+ print "Syntax error"
+ return -1
+ for o, a in opts:
+ if o == "--py":
+ compilePythonDir(a); return 0
+ if o == "--spy":
+ compileSpyceDir(a); return 0
+ if o == "--apache":
+ configHTTPD(a); return 0
+ if o == "--apacheUN":
+ unconfigHTTPD(); return 0
+ if o == "--apacheRestart":
+ restartApache(); return 0
+ print "Syntax error"
+ return -1
+
+if __name__=='__main__':
+ sys.exit(main())
diff --git a/system/python/spyce/makefile b/system/python/spyce/makefile
new file mode 100644
index 0000000000..ef667d983f
--- /dev/null
+++ b/system/python/spyce/makefile
@@ -0,0 +1,160 @@
+PYTHON := $(shell which python)
+SPYCE_VERSION = $(shell $(PYTHON) -c "import spyce; print spyce.__version__")
+SPYCE_RELEASE = $(shell $(PYTHON) -c "import spyce; print spyce.__release__")
+
+SRC := $(wildcard *.py) $(wildcard modules/*.py) $(wildcard tags/*.py)
+OTHER := CHANGES LICENCE README THANKS spyceApache.conf spyce.conf.eg spyce.mime
+DOC_SRC := $(wildcard docs/*.spy) docs/*.gif docs/examples/*.gif
+DOC = $(wildcard docs/*.html) docs/*.gif
+EXAMPLES := $(wildcard docs/examples/*.spy) $(wildcard docs/examples/*.spi) $(wildcard docs/examples/*.tmpl) $(wildcard docs/examples/*.py) $(wildcard docs/examples/*.gif)
+
+SFUSER := batripler
+SFCVSanon := :pserver:anonymous@cvs1.sourceforge.net:/cvsroot/spyce
+SFCVSdev := :ext:$(SFUSER)@cvs1.sourceforge.net:/cvsroot/spyce
+SFCVS := $(SFCVSdev)
+SF_SPYCE_DIR := /home/groups/s/sp/spyce
+
+ssh := ssh -1 -x
+scp := scp -o Protocol=1
+
+COMPILED = $(SRC:.py=.pyc) $(SRC:.py=.pyo)
+
+# install paths
+DESTDIR := /
+INSTALL_ROOT := $(DESTDIR)
+INSTALL_CODE := $(INSTALL_ROOT)/usr/share
+
+RPMROOT := /home/barr/misc/rpm
+
+.PHONY: all compile clean remake tgz rpm www
+
+all: compile docs
+
+# make this a dependency every time you use $PYTHON or $SPYCE_VERSION
+versionchk: $(PYTHON)
+ $(PYTHON) verchk.py
+ touch versionchk
+
+clean: versionchk
+ -rm versionchk
+ -rm -f spyce.spec spyce.nsi
+ -rm -f *.pyc modules/*.pyc tags/*.pyc
+ -rm -f *.pyo modules/*.pyo tags/*.pyo
+ -rm -f spyce-$(SPYCE_VERSION)-$(SPYCE_RELEASE).tgz
+ -rm -f spyce-$(SPYCE_VERSION)-$(SPYCE_RELEASE).noarch.rpm
+ -rm -f $(RPMROOT)/SOURCES/spyce-$(SPYCE_VERSION)-$(SPYCE_RELEASE).tgz
+ -rm -f $(RPMROOT)/SRPMS/spyce-$(SPYCE_VERSION)-$(SPYCE_RELEASE).src.rpm
+ -rm -f $(RPMROOT)/RPMS/noarch/spyce-$(SPYCE_VERSION)-$(SPYCE_RELEASE).noarch.rpm
+ -rm -rf $(RPMROOT)/BUILD/spyce-$(SPYCE_VERSION)
+ -$(MAKE) -C docs clean
+
+perm:
+ chmod a+r -R .
+ chmod a+rx . `find . -type d`
+ chmod a+x run_*.py verchk.py
+ chmod a+x spyce.py spyceCGI.py
+
+remake: clean all
+
+compile: $(COMPILED)
+
+# make documentation
+docs: compile
+ @$(MAKE) -C docs
+
+# make source tarball
+tgz: versionchk
+ @echo "Making clean source tarball: spyce-$(SPYCE_VERSION)-$(SPYCE_RELEASE).tgz"
+ -rm -rf spyce-$(SPYCE_VERSION)
+ cvs -d $(SFCVS) export -d spyce-$(SPYCE_VERSION) -D now spyce
+ chmod a+r -R spyce-$(SPYCE_VERSION)
+ chmod a+x `find spyce-$(SPYCE_VERSION) -type d`
+ chmod a+x spyce-$(SPYCE_VERSION)/run_*.py spyce-$(SPYCE_VERSION)/verchk.py
+ chmod a+x spyce-$(SPYCE_VERSION)/spyce.py spyce-$(SPYCE_VERSION)/spyceCGI.py
+ # process .nsi.in so that we can just use .tgz to make .exe installer
+ cd spyce-$(SPYCE_VERSION); make spyce.nsi; rm -f *.pyc *.pyo; cd ..
+ tar --totals -czf spyce-$(SPYCE_VERSION)-$(SPYCE_RELEASE).tgz spyce-$(SPYCE_VERSION)
+ rm -rf spyce-$(SPYCE_VERSION)
+
+# make rpm
+rpm: versionchk tgz spyce.spec
+ cp spyce-$(SPYCE_VERSION)-$(SPYCE_RELEASE).tgz $(RPMROOT)/SOURCES
+ rpmbuild -ba spyce.spec
+ cp $(RPMROOT)/RPMS/noarch/spyce-$(SPYCE_VERSION)-$(SPYCE_RELEASE).noarch.rpm .
+
+# install Spyce (used for manual install and by rpm scripts)
+install: compile docs
+ @echo "Installing Spyce python module in: $(INSTALL_CODE)/spyce"
+ @for f in `find . -type d`; do \
+ mkdir -p $(INSTALL_CODE)/spyce/$$f; \
+ chmod a+rx $(INSTALL_CODE)/spyce/$$f; \
+ done
+ @for f in $(SRC) $(COMPILED) $(OTHER) $(DOC) $(EXAMPLES); do \
+ install -m 644 $$f $(INSTALL_CODE)/spyce/$$f; \
+ done
+ @chmod a+rx $(INSTALL_CODE)/spyce/run_*.py $(INSTALL_CODE)/spyce/verchk.py
+ @chmod a+rx $(INSTALL_CODE)/spyce/spyce.py $(INSTALL_CODE)/spyce/spyceCGI.py
+
+# uninstall Spyce (used for manual install and by rpm scripts)
+uninstall:
+ @echo "Removing main Spyce directory: $(INSTALL_CODE)/spyce"
+ @-rm -rf $(INSTALL_CODE)/spyce
+
+# generate python compiled (bytecode) files
+$(COMPILED): $(SRC)
+ $(PYTHON) -c "exec '''import py_compile,string,os\nfor i in string.split('$+', ' '):\n print 'Compiling .pyc: '+i; py_compile.compile(i)\n'''"
+ $(PYTHON) -OO -c "exec '''import py_compile,string,os\nfor i in string.split('$+', ' '):\n print 'Compiling .pyo: '+i; py_compile.compile(i)\n'''"
+ chmod a+r $(COMPILED)
+
+%.pyc: %.py versionchk
+ $(PYTHON) -c "import py_compile; py_compile.compile('$<')"
+ chmod a+r $<
+
+%.pyo: %.py versionchk
+ $(PYTHON) -O -c "import py_compile; py_compile.compile('$<')"
+ chmod a+r $<
+
+spyce.spec: spyce.spec.in spyce.py
+ cat spyce.spec.in | sed "s/__VERSION__/${SPYCE_VERSION}/" | sed "s/__RELEASE__/${SPYCE_RELEASE}/" > spyce.spec
+
+spyce.nsi: spyce.nsi.in spyce.py
+ cat spyce.nsi.in | sed "s/__VERSION__/${SPYCE_VERSION}/" | sed "s/__RELEASE__/${SPYCE_RELEASE}/" > spyce.nsi
+
+
+# update sourceforge
+sf: clean tgz compile
+ -rm -r www
+ mkdir www; mkdir www/htdocs; mkdir www/htdocs/examples; mkdir www/cgi-bin; mkdir www/cgi-bin/eg
+ # docs
+ @$(MAKE) -C docs sf
+ cp docs/*.html docs/*.gif docs/*.ico www/htdocs
+ # examples
+ cp docs/examples/*.spy docs/examples/*.spi docs/examples/*.tmpl www/htdocs/examples
+ # exec
+ cp spyce-$(SPYCE_VERSION)-$(SPYCE_RELEASE).tgz www
+ cd www; tar -xzf spyce-$(SPYCE_VERSION)-$(SPYCE_RELEASE).tgz; mv spyce-$(SPYCE_VERSION) spyce; rm spyce-$(SPYCE_VERSION)-$(SPYCE_RELEASE).tgz; cd spyce; make compile; cd ../..
+ # cgi
+ cp docs/examples/*.spy docs/examples/*.spi docs/examples/*.py docs/examples/*.tmpl docs/examples/*.gif www/cgi-bin/eg
+ cd www; for f in cgi-bin/eg/*.spy; do spyce/misc/addfirstline.sh $$f '#!/usr/bin/python ../../spyce/run_spyceCGI.py'; done; cd ..
+ # package it all up
+ tar -czvf www.tgz www/
+ -rm -r www
+ # send it over
+ $(scp) www.tgz $(SFUSER)@shell.sourceforge.net:.
+ -rm www.tgz
+ make clean
+ # unpackage it there
+ $(ssh) $(SFUSER)@shell.sourceforge.net 'tar -xzf www.tgz; rm www.tgz; cd www; chmod -R a+r .; chmod a+x `find . -type d`; chmod a+x cgi-bin/eg/*.spy; cd spyce; make perm; cd ../..; chown -R :spyce www; chmod -R g+rw .; chmod g+x `find www -type d`'
+ # out with the old and in with the new
+ $(ssh) $(SFUSER)@shell.sourceforge.net 'pushd $(SF_SPYCE_DIR); rm -rf cgi-bin htdocs spyce; popd; mv www/* $(SF_SPYCE_DIR); rmdir www'
+
+sfcontrib:
+ # contribs
+ python run_spyceCmd.py -O contrib/*.spy
+ $(scp) -r contrib $(SFUSER)@shell.sourceforge.net:$(SF_SPYCE_DIR)/htdocs
+
+# upload files to sourceforge file release system
+upload: versionchk rpm
+ ncftpput upload.sourceforge.net incoming spyce-$(SPYCE_VERSION)-$(SPYCE_RELEASE).tgz spyce-$(SPYCE_VERSION)-$(SPYCE_RELEASE).noarch.rpm
+ make clean
+
diff --git a/system/python/spyce/modules/automaton.py b/system/python/spyce/modules/automaton.py
new file mode 100644
index 0000000000..68a8c9a8ae
--- /dev/null
+++ b/system/python/spyce/modules/automaton.py
@@ -0,0 +1,79 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+from spyceModule import spyceModule
+
+__doc__ = '''Automaton module allows Spyce users to create websites with
+state machine-based application flows. One can define an automaton
+programmatically using the start(), transition() and begin methods. The
+automaton is the executed (one step per request) using the step() method. This
+method accepts the current state, which should be managed by the user
+preferably via a session (keeping the information on the server), or possibly
+by get, post or cookie. The step() method then calls the recv() function on
+the given state, which returns an edge label. This edge points to the new
+state. The step() method then calls the send() method of the new state to
+generate the page content. The user should encode the new state in this
+content, or use on a subsequent request.'''
+
+SEND = 0
+RECV = 1
+EDGES = 2
+
+class automaton(spyceModule):
+ def start(self):
+ "Initialise an empty automaton"
+ self.clear()
+ def clear(self):
+ self._nodes = {}
+ self._edges = {}
+ # defining the automaton
+ def state(self, name, send, recv):
+ "Add a new automaton state"
+ self._nodes[name] = send, recv
+ self.transition(name, None, name)
+ def transition(self, state1, edge, state2):
+ "Add a new automaton transition"
+ if not self._nodes.has_key(state1):
+ raise 'state %s does not exist' % state1
+ if not self._nodes.has_key(state2):
+ raise 'state %s does not exist' % state2
+ self._edges[(state1, edge)] = state2
+ node=state
+ edge=transition
+ def begin(self, name):
+ if not self._nodes.has_key(name):
+ raise 'state %s does not exist' % name
+ self._begin = name
+ def define(self, sm, start):
+ self.clear()
+ for s1 in sm.keys():
+ self.node(s1, sm[s1][SEND], sm[s1][RECV])
+ for s1 in sm.keys():
+ for e in sm[s1][EDGES].keys():
+ self.edge(s1, e, sm[s1][EDGES][e])
+ self.begin(start)
+
+ # running the automaton
+ def step(self, state=None):
+ """Run the automaton one step: recv (old state), transition,
+ send (new state)"""
+ if state==None:
+ state = self._begin
+ else:
+ try: _, recv = self._nodes[state]
+ except: raise 'invalid state: %s' % state
+ edge = recv()
+ try: state = self._edges[(state, edge)]
+ except: raise 'invalid transition: %s,%s' % (state, edge)
+ try: send, _ = self._nodes[state]
+ except: raise 'invalid state: %s' % state
+ send()
+
+
+# rimtodo: cached state-machines
+
diff --git a/system/python/spyce/modules/compress.py b/system/python/spyce/modules/compress.py
new file mode 100644
index 0000000000..5ff0b02299
--- /dev/null
+++ b/system/python/spyce/modules/compress.py
@@ -0,0 +1,84 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+from spyceModule import spyceModule
+from cStringIO import StringIO
+import gzip, string, spyceUtil
+
+__doc__ = '''Compress module provides dynamic compression.'''
+
+OUTPUT_POSITION = 95
+
+class compress(spyceModule):
+ def start(self):
+ # install compress filter into response module
+ self._filter = FilterCompress(self)
+ self._api.getModule('response').addFilter(OUTPUT_POSITION, self._filter)
+ def finish(self, theError=None):
+ if not theError:
+ self._filter.close()
+ def init(self, gzip=None, spaces=None):
+ if gzip: self.gzip()
+ if spaces: self.spaces()
+ def spaces(self, on=1):
+ self._filter.setSpaceMode(on)
+ def gzip(self, level=None):
+ self._filter.setGZIP(level)
+
+class FilterCompress(Filter):
+ def __init__(self, module):
+ self._module = module
+ self._buf = StringIO()
+ self._flushed = 0
+ self._space = 0
+ self._gzip = None
+ self._gzipfile = None
+ def writeStatic(self, s):
+ self.write(s)
+ def writeExpr(self, s, **kwargs):
+ self.write(str(s))
+ def setSpaceMode(self, on):
+ self._space = on
+ def setGZIP(self, level):
+ if self._flushed:
+ raise 'output already flushed'
+ encodings = self._module._api.getModule('request').getHeader('Accept-Encoding')
+ if not encodings or string.find(encodings, 'gzip')<0:
+ return # ensure the browser can cope
+ if level==0:
+ self._gzip = None
+ self._gzipfile = None
+ else:
+ self._gzipfile = StringIO()
+ if level:
+ self._gzip = gzip.GzipFile(mode='w', fileobj=self._gzipfile, compresslevel=level)
+ else:
+ self._gzip = gzip.GzipFile(mode='w', fileobj=self._gzipfile)
+ def write(self, s, *args, **kwargs):
+ self._buf.write(s)
+ def flushImpl(self, final=0):
+ self._flushed = 1
+ s = self._buf.getvalue()
+ self._buf = StringIO()
+ if self._space:
+ s = spyceUtil.spaceCompact(s)
+ if self._gzip:
+ self._gzip.write(s)
+ self._gzip.flush()
+ if final:
+ self._module._api.getModule('response').addHeader('Content-Encoding', 'gzip')
+ self._gzip.close()
+ self._gzip = None
+ s = self._gzipfile.getvalue()
+ self._gzipfile.truncate(0)
+ self.next.write(s)
+ def clearImpl(self):
+ self._buf = StringIO()
+ def close(self):
+ self.flushImpl(1)
+
diff --git a/system/python/spyce/modules/cookie.py b/system/python/spyce/modules/cookie.py
new file mode 100644
index 0000000000..e17ad05a3f
--- /dev/null
+++ b/system/python/spyce/modules/cookie.py
@@ -0,0 +1,50 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+from spyceModule import spyceModule
+import Cookie, time, calendar
+
+__doc__ = """Cookie module gives users full control over browser cookie
+functionality. """
+
+class cookie(spyceModule):
+ def start(self):
+ self._cookie = None
+ def get(self, key=None):
+ "Get brower cookie(s)"
+ if self._cookie == None:
+ self._cookie = {}
+ cookie = Cookie.SimpleCookie(self._api.getModule('request').env('HTTP_COOKIE'))
+ for c in cookie.keys():
+ self._cookie[c] = cookie[c].value
+ if key:
+ if self._cookie.has_key(key):
+ return self._cookie[key]
+ else: return self._cookie
+ def __getitem__(self, key):
+ "Get browser cookie(s)"
+ return self.get(key)
+ def set(self, key, value, expire=None, domain=None, path=None, secure=0):
+ "Set browser cookie"
+ if value==None: # delete (set to expire one week ago)
+ return self.set(key, '', -60*60*24*7, domain, path, secure)
+ text = '%s=%s' % (key, value)
+ if expire != None: text = text + ';EXPIRES=%s' % time.strftime(
+ '%a, %d-%b-%y %H:%M:%S GMT',
+ time.gmtime(time.time()+expire))
+ if domain: text = text + ';DOMAIN=%s' % domain
+ if path: text = text + ';PATH=%s' % path
+ if secure: text = text + ';SECURE'
+ self._api.getModule('response').addHeader('Set-Cookie', text)
+ def delete(self, key):
+ "Delete browser cookie"
+ self.set(key, None)
+ def __delitem__(self, key):
+ "Delete browser cookie"
+ return self.delete(self, key)
+
diff --git a/system/python/spyce/modules/error.py b/system/python/spyce/modules/error.py
new file mode 100644
index 0000000000..db396294e2
--- /dev/null
+++ b/system/python/spyce/modules/error.py
@@ -0,0 +1,171 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+from spyceModule import spyceModule
+import spyceException
+import os
+
+__doc__ = '''Error module provides error-handling functionality.'''
+
+class error(spyceModule):
+ def start(self):
+ self._error = None
+ pageerrorType, pageerrorData = self._api.getPageError()
+ self.handler = lambda self, pageerrorType=pageerrorType, pageerrorData=pageerrorData: spyceHandler(self, pageerrorData, pageerrorType)
+ def finish(self, theError=None):
+ self._error = theError
+ self._fromFile = self._api.getFilename()
+ if theError:
+ self.handler(self)
+ def setHandler(self, fn):
+ if not type(fn)==type(spyceHandler):
+ raise 'parameter should be a function'
+ self.handler = fn
+ def setStringHandler(self, s):
+ if not type(s)==type(''):
+ raise 'parameter should be a string of spyce code'
+ self.handler = lambda self, s=s: spyceHandler(self, s, 'string')
+ def setFileHandler(self, f):
+ if not type(f)==type(''):
+ raise 'parameter should be a filename'
+ self.handler = lambda self, f=f: spyceHandler(self, f)
+ def getHandler(self):
+ return self.handler
+ def isError(self):
+ return not not self._error
+ def getMessage(self):
+ if self._error: return self._error.msg
+ def getType(self):
+ if self._error: return self._error.type
+ def getFile(self):
+ if self._error: return self._fromFile
+ def getTraceback(self):
+ if self._error: return self._error.traceback
+ def getString(self):
+ if self._error: return self._error.str
+ def __repr__(self):
+ if not self._error: return 'None'
+ return 'type: %s, string: %s, msg: %s, file: %s' % (
+ self.getType(), self.getString(), self.getMessage(), self.getFile())
+
+def spyceHandler(errorModule, spyceCode, type='file'):
+ try:
+ responseModule = errorModule._api.getModule('response')
+ responseModule.clear()
+ responseModule.clearHeaders()
+ responseModule.clearFilters()
+ responseModule.setContentType('text/html')
+ responseModule.setReturnCode(errorModule._api.getResponse().RETURN_OK)
+ except: pass
+ try:
+ s, file = None, None
+ if type=='file':
+ file = os.path.join(os.path.dirname(errorModule._api.getFilename()), spyceCode)
+ code = errorModule._api.spyceFile(file)
+ elif type=='string':
+ file = '<string>'
+ code = errorModule._api.spyceString(spyceCode)
+ else:
+ raise 'unrecognized handler type'
+ try:
+ s = code.newWrapper()
+ modules = errorModule._api.getModules()
+ for name in modules.keys():
+ s.setModule(name, modules[name]) # include modules as well!
+ s.spyceInit(errorModule._api.getRequest(), errorModule._api.getResponse())
+ errmod = s._startModule('error', None, None, 1)
+ errmod._error = errorModule._error
+ errmod._fromFile = errorModule._fromFile
+ s.spyceProcess()
+ finally:
+ if s:
+ s.spyceDestroy()
+ code.returnWrapper(s)
+ except spyceException.spyceRuntimeException, e:
+ errorModule._error = e
+ errorModule._fromFile = file
+ if (type, spyceCode) == ('string', defaultErrorTemplate):
+ raise # avoid infinite loop
+ else:
+ spyceHandler(errorModule, defaultErrorTemplate, 'string')
+
+defaultErrorTemplate = '''
+[[.module name=transform]]
+[[transform.expr('html_encode')]]
+<html>
+<title>Spyce exception: [[=error.getMessage()]]</title>
+<body>
+<table border=0>
+ <tr><td colspan=2><h1>Spyce exception</h1></td></tr>
+ <tr><td valign=top><b>File:</b></td><td>[[=error.getFile()]]</tr>
+ <tr><td valign=top><b>Message:</b></td>
+ <td><pre>[[=error.getMessage()]]</pre></tr>
+ <tr><td valign=top><b>Stack:</b></td><td>
+ [[ for frame in error.getTraceback(): { ]]
+ [[=frame[0] ]]:[[=frame[1] ]], in [[=frame[2] ]]:<br>
+ <table border=0><tr><td width=10></td><td>
+ <pre>[[=frame[3] ]]</pre>
+ </td></tr></table>
+ [[ } ]]
+ </td></tr>
+</table>
+</body></html>
+'''
+
+def serverHandler(theServer, theRequest, theResponse, theError):
+ try:
+ theResponse.clear()
+ theResponse.clearHeaders()
+ theResponse.setContentType('text/html')
+ theResponse.setReturnCode(theResponse.RETURN_OK)
+ except: pass
+ s = None
+ try:
+ spycecode = theServer.spyce_cache[('string', serverErrorTemplate)]
+ s = spycecode.newWrapper()
+ s.spyceInit(theRequest, theResponse)
+ s.getModule('error')._error = theError
+ s.spyceProcess()
+ finally:
+ if s:
+ s.spyceDestroy()
+ spycecode.returnWrapper(s)
+
+
+serverErrorTemplate = '''
+[[.module name=transform]]
+[[import string, spyceException
+ if isinstance(error._error, spyceException.spyceNotFound): { ]]
+ <html><body>
+ [[=error._error.file]] not found
+ [[response.setReturnCode(response._api.getResponse().RETURN_NOT_FOUND)]]
+ </body></html>
+[[ } elif isinstance(error._error, spyceException.spyceForbidden): { ]]
+ <html><body>
+ [[=error._error.file]] forbidden
+ [[response.setReturnCode(response._api.getResponse().RETURN_FORBIDDEN)]]
+ </body></html>
+[[ } elif isinstance(error._error, spyceException.spyceSyntaxError): { ]]
+ <html><body><pre>
+ [[=transform.html_encode(`error._error`)]]
+ </pre></body></html>
+[[ } elif isinstance(error._error, spyceException.pythonSyntaxError): { ]]
+ <html><body><pre>
+ [[=transform.html_encode(`error._error`)]]
+ </pre></body></html>
+[[ } elif isinstance(error._error, SyntaxError): { ]]
+ <html><body><pre>
+ Syntax error at [[=error._error.filename]]:[[=error._error.lineno]] -
+ [[=transform.html_encode(error._error.text)]] [[
+ if not error._error.offset==None: {
+ print ' '*error._error.offset+'^'
+ }
+ ]]
+ </pre></body></html>
+[[ } else: { raise error._error } ]]
+'''
diff --git a/system/python/spyce/modules/include.py b/system/python/spyce/modules/include.py
new file mode 100644
index 0000000000..ab7bd9ddb1
--- /dev/null
+++ b/system/python/spyce/modules/include.py
@@ -0,0 +1,117 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+from spyceModule import spyceModule
+import os, re
+
+__doc__ = """Include module is used to assist the inclusion of abitrary
+elements/files into a Spyce file. It can also support the notion of an
+'inclusion context'."""
+
+class include(spyceModule):
+ def start(self):
+ self.context = None
+ self.vars = None
+ self.fromFile = None
+ def spyce(self, file, context=None):
+ "Include a Spyce file"
+ file = os.path.join(os.path.dirname(self._api.getFilename()), file)
+ result = s = code = None
+ try:
+ code = self._api.spyceFile(file)
+ s = code.newWrapper()
+ modules = self._api.getModules()
+ for name in modules.keys():
+ s.setModule(name, modules[name]) # include module as well!
+ s.spyceInit(self._api.getRequest(), self._api.getResponse())
+ incmod = s._startModule('include', None, None, 1)
+ incmod.context = context
+ if type(context)==type({}):
+ incmod.vars = spyceVars(context)
+ incmod.fromFile = self._api.getFilename()
+ result = s.spyceProcess()
+ finally:
+ if s:
+ s.spyceDestroy()
+ code.returnWrapper(s)
+ return result
+ def spyceStr(self, file, context=None):
+ stdout = self._api.getModule('stdout')
+ stdout.push()
+ try:
+ result = self.spyce(file, context)
+ finally:
+ output = stdout.pop()
+ return output
+ def dump(self, file, binary=0):
+ "Include a plain text file, verbatim"
+ file = os.path.join(os.path.dirname(self._api.getFilename()), file)
+ f = None
+ try:
+ if binary: mode='rb'
+ else: mode='r'
+ f = open(file, mode)
+ buf = f.read()
+ finally:
+ if f: f.close()
+ return buf
+ def spycecode(self, file=None, string=None, html=None, code=None, eval=None, directive=None, comment=None):
+ "Emit formatted Spyce code"
+ if not html: html = ('<font color="#000000"><b>', '</b></font>')
+ if not code: code = ('<font color="#0000CC">', '</font>')
+ if not eval: eval = ('<font color="#CC0000">', '</font>')
+ if not directive: directive = ('<font color="#CC00CC">', '</font>')
+ if not comment: comment = ('<font color="#777777">', '</font>')
+ import spyceCompile
+ from StringIO import StringIO
+ if (file and string) or (not file and not string):
+ raise 'must specify either file or string, and not both'
+ if file:
+ f = None
+ try:
+ file = os.path.join(os.path.dirname(self._api.getFilename()), file)
+ f = open(file, 'r')
+ string = f.read()
+ finally:
+ if f: f.close()
+ html_encode = self._api.getModule('transform').html_encode
+ try:
+ tokens = spyceCompile.spyceTokenize(string)
+ buf = StringIO()
+ markupstack = []
+ buf.write(html[0]); markupstack.append(html[1])
+ for type, text, _, _ in tokens:
+ if type in (spyceCompile.T_STMT, spyceCompile.T_CHUNK, spyceCompile.T_CHUNKG,):
+ buf.write(code[0]); markupstack.append(code[1])
+ if type in (spyceCompile.T_LAMBDA,):
+ buf.write(html[0]); markupstack.append(html[1])
+ if type in (spyceCompile.T_EVAL,):
+ buf.write(eval[0]); markupstack.append(eval[1])
+ if type in (spyceCompile.T_DIRECT,):
+ buf.write(directive[0]); markupstack.append(directive[1])
+ if type in (spyceCompile.T_CMNT,):
+ buf.write(comment[0]); markupstack.append(comment[1])
+ buf.write(html_encode(text))
+ if type in (spyceCompile.T_END_CMNT, spyceCompile.T_END,):
+ buf.write(markupstack.pop())
+ while markupstack:
+ buf.write(markupstack.pop())
+ return buf.getvalue()
+ except:
+ raise
+ raise 'error tokenizing!'
+
+class spyceVars:
+ def __init__(self, vars):
+ self.__dict__['vars'] = vars
+ def __getattr__(self, name):
+ try: return self.__dict__['vars'][name]
+ except KeyError: raise AttributeError
+ def __setattr__(self, name, value):
+ self.__dict__['vars'][name] = value
+
diff --git a/system/python/spyce/modules/pool.py b/system/python/spyce/modules/pool.py
new file mode 100644
index 0000000000..5b8d1a5c99
--- /dev/null
+++ b/system/python/spyce/modules/pool.py
@@ -0,0 +1,45 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+from spyceModule import spyceModule
+
+__doc__ = """Pool module supports the creation of server-pooled objects. The
+single pool is shared among all Spyce execution context residing on a given
+server, and remains until the server dies. It is often useful to store
+database connections, and other variables that are expensive to compute on a
+per-request basis. """
+
+class pool(spyceModule):
+ def start(self):
+ "Define or retrieve the pool."
+ self._serverobject = self._api.getServerObject()
+ if 'pool' not in dir(self._serverobject):
+ self._serverobject.pool = {}
+ self.server = self._api.getServerGlobals()
+ def __getitem__(self, key):
+ "Get an item from the pool."
+ return self._serverobject.pool[key]
+ def __setitem__(self, key, value):
+ "Set an item in the pool."
+ self._serverobject.pool[key] = value
+ def __delitem__(self, key):
+ "Delete an item in the pool."
+ del self._serverobject.pool[key]
+ def keys(self):
+ "Return the pool hash keys."
+ return self._serverobject.pool.keys()
+ def values(self):
+ "Return the pool hash values."
+ return self._serverobject.pool.values()
+ def has_key(self, key):
+ "Test of existence of key in pool."
+ return self._serverobject.pool.has_key(key)
+ def clear(self):
+ "Purge the pool of all items."
+ return self._serverobject.pool.clear()
+
diff --git a/system/python/spyce/modules/redirect.py b/system/python/spyce/modules/redirect.py
new file mode 100644
index 0000000000..9d767cac32
--- /dev/null
+++ b/system/python/spyce/modules/redirect.py
@@ -0,0 +1,53 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+from spyceModule import spyceModule
+import spyceException
+
+__doc__ = '''Redirect module provides support for different kinds of request
+redirection, currently: internal, external and externalRefresh.
+- internal: flush the current output bufffer (assuming it has not been sent)
+ and raise an appropriate exception that will start the processing of the
+ new file, if left to percolate all the way to the Spyce engine. The
+ browser url does not change.
+- external: send an HTTP return code that signals a permanent or temporary
+ page move, depending on the boolean parameter. Spyce file execution will
+ continue to termination, but the output buffer is flushed at the end and a
+ special redirect document is generated. The browser is expected, as per the
+ standard, to immediately redirect and perform a new request, thus the url
+ will change.
+- externalRefresh: send an HTTP Refresh header that requests a page refresh to
+ a (possibly) new location within some number of seconds. The current Spyce
+ page will be displayed until that time. This is often used to display a page
+ before redirecting the browser to a file download.
+'''
+
+class redirect(spyceModule):
+ def start(self):
+ self.clear = 0
+ def finish(self, theError=None):
+ if not theError:
+ if self.clear:
+ self._api.getModule('response').clear()
+ def internal(self, file):
+ "Perform an internal redirect."
+ self._api.getModule('response').clearHeaders()
+ self._api.getModule('response').clear()
+ file = os.path.join(os.path.dirname(self._api.getFilename()), file)
+ raise spyceException.spyceRedirect(file)
+ def external(self, url, permanent=0):
+ "Perform an external redirect."
+ self._api.getModule('response').addHeader('Location', url)
+ if permanent:
+ self._api.getModule('response').setReturnCode(self._api.getResponse().RETURN_MOVED_PERMANENTLY)
+ else:
+ self._api.getModule('response').setReturnCode(self._api.getResponse().RETURN_MOVED_TEMPORARILY)
+ self.clear = 1
+ def externalRefresh(self, url, sec=0):
+ "Perform an external redirect, via refresh."
+ self._api.getModule('response').addHeader('Refresh', '%d; URL=%s' % (sec, url))
diff --git a/system/python/spyce/modules/request.py b/system/python/spyce/modules/request.py
new file mode 100644
index 0000000000..f1a1cef5df
--- /dev/null
+++ b/system/python/spyce/modules/request.py
@@ -0,0 +1,224 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+from spyceModule import spyceModule
+import cgi, string, urlparse, spyceUtil
+
+__doc__ = """Request module provides access to the browser request
+information. """
+
+class request(spyceModule):
+ def start(self):
+ "Initialise module variables"
+ self._get = None
+ self._postfields = None
+ def uri(self, component=None):
+ "Return request URI, or URI component"
+ theuri = self._api.getRequest().env()['REQUEST_URI']
+ if not component:
+ return theuri
+ else:
+ component = string.lower(component)
+ if component == 'scheme': component = 0
+ elif component == 'location': component = 1
+ elif component == 'path': component = 2
+ elif component == 'parameters': component = 3
+ elif component == 'query': component = 4
+ elif component == 'fragment': component = 5
+ else: raise 'unknown uri component'
+ return urlparse.urlparse(theuri)[component]
+ def uri_scheme(self):
+ "Return request URI scheme, ie. http (usually)"
+ return urlparse.urlparse(self.uri())[0]
+ def uri_location(self):
+ "Return request URI scheme, ie. http (usually)"
+ return urlparse.urlparse(self.uri())[1]
+ def uri_path(self):
+ "Return request URI path component"
+ return urlparse.urlparse(self.uri())[2]
+ def method(self):
+ "Return request method: get/post/..."
+ return string.upper(self._api.getRequest().env()['REQUEST_METHOD'])
+ def query(self):
+ "Return request query string"
+ return self._api.getRequest().env()['QUERY_STRING']
+ def filename(self, relative=None):
+ "Return original Spyce filename"
+ myfile = self._api.getFilename()
+ if relative==None:
+ return myfile
+ else:
+ return os.path.normpath(os.path.join(os.path.dirname(myfile), relative))
+ def default(self, value, value2):
+ "Return value, or value2 if value==None"
+ if value==None: return value2
+ return value
+ def _getInit(self):
+ if self._get==None:
+ self._get = cgi.parse_qs(self.query(), 1)
+ self._get1 = {}
+ self._getL = {}
+ self._getL1 = {}
+ for key in self._get.keys():
+ self._getL[string.lower(key)] = []
+ for key in self._get.keys():
+ keyL = string.lower(key)
+ self._getL[keyL] = self._getL[keyL] + self._get[key]
+ for key in self._get.keys():
+ self._get1[key] = self._get[key][0]
+ for keyL in self._getL.keys():
+ self._getL1[keyL] = self._getL[keyL][0]
+ def get(self, name=None, default=None, ignoreCase=0):
+ "Return GET parameter(s) list(s)"
+ self._getInit()
+ if ignoreCase:
+ if name: name = string.lower(name)
+ value = spyceUtil.extractValue(self._getL, name)
+ else:
+ value = spyceUtil.extractValue(self._get, name)
+ return self.default(value, default)
+ def get1(self, name=None, default=None, ignoreCase=0):
+ "Return single GET parameter(s)"
+ self._getInit()
+ if ignoreCase:
+ if name: name = string.lower(name)
+ value = spyceUtil.extractValue(self._getL1, name)
+ else:
+ value = spyceUtil.extractValue(self._get1, name)
+ return self.default(value, default)
+ def _postInit(self):
+ if self._postfields==None:
+ if hasattr(self._api.getRequest(), 'spycepostinfo'):
+ # stream was already parsed (possibly this is an internal redirect)
+ (self._post, self._post1, self._file,
+ self._postL, self._postL1, self._fileL,
+ self._postfields) = self._api.getRequest().spycepostinfo
+ return
+ self._post = {}
+ self._post1 = {}
+ self._file = {}
+ self._postL = {}
+ self._postL1 = {}
+ self._fileL = {}
+ self._postfields={}
+ try: len = int(str(self.env('CONTENT_LENGTH')))
+ except: len=0
+ if self.method()=='POST' and len:
+ self._postfields = cgi.FieldStorage(fp=self._api.getRequest(), environ=self.env(), keep_blank_values=1)
+ for key in self._postfields.keys():
+ if type(self._postfields[key]) == type( [] ):
+ self._post[key] = map(lambda attr: attr.value, self._postfields[key])
+ self._post1[key] = self._post[key][0]
+ elif not self._postfields[key].filename:
+ self._post[key] = [self._postfields[key].value]
+ self._post1[key] = self._post[key][0]
+ else:
+ self._file[key] = self._fileL[string.lower(key)] = self._postfields[key]
+ for key in self._post.keys():
+ self._postL[string.lower(key)] = []
+ for key in self._post.keys():
+ keyL = string.lower(key)
+ self._postL[keyL] = self._postL[keyL] + self._post[key]
+ for keyL in self._postL.keys():
+ self._postL1[keyL] = self._postL[keyL][0]
+ # save parsed information in request object to prevent reparsing (on redirection)
+ self._api.getRequest().spycepostinfo = (self._post, self._post1, self._file,
+ self._postL, self._postL1, self._fileL, self._postfields)
+ def post(self, name=None, default=None, ignoreCase=0):
+ "Return POST parameter(s) list(s)"
+ self._postInit()
+ if ignoreCase:
+ if name: name = string.lower(name)
+ value = spyceUtil.extractValue(self._postL, name)
+ else:
+ value = spyceUtil.extractValue(self._post, name)
+ return self.default(value, default)
+ def post1(self, name=None, default=None, ignoreCase=0):
+ "Return single POST parameter(s)"
+ self._postInit()
+ if ignoreCase:
+ if name: name = string.lower(name)
+ value = spyceUtil.extractValue(self._postL1, name)
+ else:
+ value = spyceUtil.extractValue(self._post1, name)
+ return self.default(value, default)
+ def file(self, name=None, ignoreCase=0):
+ "Return POSTed file(s)"
+ self._postInit()
+ if ignoreCase:
+ if name: name = string.lower(name)
+ return spyceUtil.extractValue(self._fileL, name)
+ else:
+ return spyceUtil.extractValue(self._file, name)
+ def env(self, name=None, default=None):
+ "Return other request (CGI) environment variables"
+ return self.default(self._api.getRequest().env(name), default)
+ def getHeader(self, type=None):
+ "Return browser HTTP header(s)"
+ return self._api.getRequest().getHeader(type)
+ def __getitem__(self, key):
+ if type(key) == type(0):
+ return self.getpost().keys()[key]
+ else:
+ v = self.get1(key)
+ if v!=None: return v
+ v = self.post1(key)
+ if v!=None: return v
+ v = self.file(key)
+ if v!=None: return v
+ def __repr__(self):
+ return ''
+ def __multidict(self, *args):
+ args = list(args)
+ args.reverse()
+ dict = {}
+ for d in args:
+ for k in d.keys():
+ dict[k] = d[k]
+ return dict
+ def getpost(self, name=None, default=None, ignoreCase=0):
+ "Return get() if not None, otherwise post() if not None, otherwise default"
+ if name==None:
+ self._getInit()
+ self._postInit()
+ return self.__multidict(self._get, self._post)
+ else:
+ value = self.get(name, None, ignoreCase)
+ if value==None: value = self.post(name, default, ignoreCase)
+ return value
+ def getpost1(self, name=None, default=None, ignoreCase=0):
+ "Return get1() if not None, otherwise post1() if not None, otherwise default"
+ if name==None:
+ self._getInit()
+ self._postInit()
+ return self.__multidict(self._get1, self._post1)
+ else:
+ value = self.get1(name, None, ignoreCase)
+ if value==None: value = self.post1(name, default, ignoreCase)
+ return value
+ def postget(self, name=None, default=None, ignoreCase=0):
+ "Return post() if not None, otherwise get() if not None, otherwise default"
+ if name==None:
+ self._getInit()
+ self._postInit()
+ return self.__multidict(self._post, self._get)
+ else:
+ value = self.post(name, None, ignoreCase)
+ if value==None: value = self.get(name, default, ignoreCase)
+ return value
+ def postget1(self, name=None, default=None, ignoreCase=0):
+ "Return post1() if not None, otherwise get1() if not None, otherwise default"
+ if name==None:
+ self._getInit()
+ self._postInit()
+ return self.__multidict(self._post1, self._get1)
+ else:
+ value = self.post1(name, None, ignoreCase)
+ if value==None: value = self.get1(name, default, ignoreCase)
+ return value
+
diff --git a/system/python/spyce/modules/response.py b/system/python/spyce/modules/response.py
new file mode 100644
index 0000000000..e68ba363a9
--- /dev/null
+++ b/system/python/spyce/modules/response.py
@@ -0,0 +1,186 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+from spyceModule import spyceModule
+import string, time
+
+__doc__ = '''Response module provides user control over the browser
+response.'''
+
+class response(spyceModule):
+ def start(self):
+ self.clearFilters()
+ self._unbuffer = 0
+ self._ioerror = 0
+ self._api.registerResponseCallback(self.syncResponse)
+ self.syncResponse()
+ def syncResponse(self):
+ self._response = self._api.getResponse()
+ def finish(self, theError=None):
+ self._api.unregisterResponseCallback(self.syncResponse)
+ if not theError:
+ self._filter.flush(1)
+ def clearFilters(self):
+ self._filter = FilterUnify(self)
+ self._filterList = [(99, self._filter)]
+ def addFilter(self, level, filter):
+ 'Inject filter functions into output stream at given level of precedence'
+ filterExists = None
+ for i in range(len(self._filterList)):
+ l, _ = self._filterList[i]
+ if l==level:
+ _, filterExists = self._filterList[i]
+ del self._filterList[i]
+ break
+ if filter:
+ self._filterList.append((level, filter))
+ self._filterList.sort()
+ for i in range(len(self._filterList)-1):
+ l1, f1 = self._filterList[i]
+ l2, f2 = self._filterList[i+1]
+ f1.setNext(f2)
+ _, self._filter = self._filterList[0]
+ return filterExists
+
+ # user functions
+ def write(self, s):
+ "Write out a dynamic (code) string."
+ try:
+ self._filter.write(s)
+ if self._unbuffer: self.flush()
+ except IOError:
+ self._ioerror = 1
+ def writeln(self, s):
+ "Writeln out a dynamic (code) string."
+ self.write(s+'\n')
+ def writeStatic(self, s):
+ "Write out a static string."
+ try:
+ self._filter.writeStatic(s)
+ if self._unbuffer: self.flush()
+ except IOError:
+ self._ioerror = 1
+ def writeExpr(self, s, **kwargs):
+ "Write out an expression result."
+ try:
+ apply(self._filter.writeExpr, (s,), kwargs)
+ if self._unbuffer: self.flush()
+ except IOError:
+ self._ioerror = 1
+ def clear(self):
+ "Clear the output buffer. (must not be unbuffered)"
+ self._filter.clear()
+ def flush(self, stopFlag=0):
+ "Flush resident buffer."
+ try:
+ self._filter.flush(stopFlag)
+ except IOError:
+ self._ioerror = 1
+ def setContentType(self, ct):
+ "Set document content type. (must not be unbuffered)"
+ self._response.setContentType(ct)
+ def setReturnCode(self, code):
+ "Set HTTP return (status) code"
+ self._response.setReturnCode(int(code))
+ def isCancelled(self):
+ return self._ioerror
+ def addHeader(self, type, data, replace=0):
+ "Add an HTTP header. (must not be unbuffered)"
+ if string.find(type, ':') != -1:
+ raise 'HTTP header type should not contain ":" (colon).'
+ self._response.addHeader(type, data, replace)
+ def clearHeaders(self):
+ "Clear all HTTP headers (must not be unbuffered)"
+ self._response.clearHeaders()
+ def unbuffer(self):
+ "Turn off output stream buffering; flush immediately to browser."
+ self._unbuffer = 1
+ self.flush()
+ def timestamp(self, thetime=None):
+ "Timestamp response with a HTTP Date header"
+ self.addHeader('Date', _genTimestampString(thetime), 1)
+ def expires(self, thetime=None):
+ "Add HTTP expiration headers"
+ self.addHeader('Expires', _genTimestampString(thetime), 1)
+ def expiresRel(self, secs=0):
+ "Set response expiration (relative to now) with a HTTP Expires header"
+ self.expires(int(time.time())+secs)
+ def lastModified(self, thetime=-1):
+ "Set last modification time"
+ if thetime==-1:
+ filename = self._api.getFilename()
+ if not filename or not os.path.exists(filename):
+ raise 'request filename not found; can not determine last modification time'
+ thetime = os.stat(filename)[9] # file ctime
+ self.addHeader('Last-Modified', _genTimestampString(thetime), 1)
+ # ensure last modified before timestamp, at least when we're generating it
+ if thetime==None: self.timestamp()
+ def uncacheable(self):
+ "Ensure that compliant clients and proxies don't cache this response"
+ self.addHeader('Cache-Control', 'no-store, no-cache, must-revalidate')
+ self.addHeader('Pragma', 'no-cache')
+ def __repr__(self):
+ s = []
+ s.append('filters: %s' % len(self._filterList))
+ s.append('unbuffered: %s' % self._unbuffer)
+ return string.join(s, ', ')
+
+class Filter:
+ def setNext(self, filter):
+ self.next = filter
+ def write(self, s):
+ s = self.dynamicImpl(s)
+ self.next.write(s)
+ def writeStatic(self, s):
+ s = self.staticImpl(s)
+ self.next.writeStatic(s)
+ def writeExpr(self, s, **kwargs):
+ s = apply(self.exprImpl, (s,), kwargs)
+ apply(self.next.writeExpr, (s,), kwargs)
+ def flush(self, stopFlag=0):
+ self.flushImpl()
+ self.next.flush(stopFlag)
+ def clear(self):
+ self.clearImpl()
+ self.next.clear()
+ def dynamicImpl(self, s, *args, **kwargs):
+ raise 'not implemented'
+ def staticImpl(self, s, *args, **kwargs):
+ raise 'not implemented'
+ def exprImpl(self, s, *args, **kwargs):
+ raise 'not implemented'
+ def flushImpl(self):
+ raise 'not implemented'
+ def clearImpl(self):
+ raise 'not implemented'
+
+class FilterUnify(Filter):
+ def __init__(self, mod):
+ self.mod = mod
+ self.mod._api.registerResponseCallback(self.syncResponse)
+ self.syncResponse()
+ def syncResponse(self):
+ response = self.mod._api.getResponse()
+ self.write = response.write
+ self.writeStatic = response.write
+ self.flush = response.flush
+ self.clear = response.clear
+ def writeExpr(self, s, **kwargs):
+ self.write(str(s))
+ def setNext(self, filter):
+ pass # we are always at the end
+
+def _genTimestampString(thetime=None):
+ "Generate timestamp string"
+ if thetime==None:
+ thetime = int(time.time())
+ if type(thetime)==type(0):
+ thetime = time.strftime('%a, %d %b %Y %H:%M:%S %Z', time.localtime(thetime))
+ if type(thetime)==type(''):
+ return thetime
+ raise 'thetime value should be None or string or integer (seconds)'
diff --git a/system/python/spyce/modules/session.py b/system/python/spyce/modules/session.py
new file mode 100644
index 0000000000..ca0b202188
--- /dev/null
+++ b/system/python/spyce/modules/session.py
@@ -0,0 +1,368 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+from spyceModule import spyceModule
+import re, time, string, random
+import spyceLock
+try:
+ import cPickle
+ pickle = cPickle
+except:
+ import pickle
+
+__doc__ = '''Session module provides support for session management - the
+storage of variables on the server between requests under some short
+identifier.
+
+A user must call setHandler() to determine how the sessions are stored, before
+using the other session methods. The get(), set() and delete() methods provide
+access to the session information.
+
+The autoSession() method will turn on the automatic session management
+(loading and saving the session). When automatic session management is turned
+on the session information, identifier, parameter name and browser method are
+stored in the variables called auto, autoID, autoName and autoMethod,
+respectively.'''
+
+class session(spyceModule):
+ def start(self):
+ "Initialise the session module variables."
+ self._serverobject = self._api.getServerObject()
+ if 'session' not in dir(self._serverobject):
+ self._serverobject.session = sessionHandlerRegistry()
+ self._handler = None
+ self._clearAutoSession()
+ def finish(self, theError=None):
+ "Save the session, if automatic session management is turned on."
+ if self.autoID:
+ self.set(self.auto, self.autoExpire, self.autoID)
+ if self.autoMethod=='cookie':
+ self._api.getModule('cookie').set(self.autoName, self.autoID)
+ sessionCleanup(self._serverobject.session)
+ def init(self, handler=None, *args, **kwargs):
+ if handler:
+ session = apply(self.setHandler, (handler,)+args)
+ if kwargs.has_key('auto') and kwargs['auto']:
+ auto = kwargs['auto']
+ if type(auto) != type(()):
+ auto = (auto,)
+ apply(session.autoSession, auto)
+ def setHandler(self, file_name, *params):
+ "Select a session handler."
+ file_name = string.split(file_name, ':')
+ if len(file_name)==1: file, name = None, file_name[0]
+ else: file, name = file_name[:2]
+ if file: handler = self._api.loadModule(name, file, self._api.getFilename())
+ else: handler = eval(name)
+ self._handler = apply(handler, (self,)+params)
+ self._serverobject.session.add(self._handler)
+ return self
+ def get(self, id): # method deletes session, if stale
+ "Retrieve session information."
+ if not self._handler: raise 'call setHandler to initialise'
+ return self._handler.get(id)
+ def delete(self, id=None):
+ "Delete session information."
+ if not self._handler: raise 'call setHandler to initialise'
+ if not id:
+ id = self.autoID
+ self._clearAutoSession()
+ return self._handler.delete(id)
+ def set(self, state, expire, id=None):
+ "Set session information."
+ if not self._handler: raise 'call setHandler to initialise'
+ return self._handler.set(state, expire, id)
+ def clear(self):
+ "Clear all session information in current handler."
+ if not self._handler: raise 'call setHandler to initialise'
+ return self._handler.clear()
+ def autoSession(self, expire, method='cookie', name='spyceSession'):
+ "Turn on automatic session management."
+ if not self._handler: raise 'call setHandler to initialise'
+ method = string.lower(method)
+ if method=='cookie': self.autoID = self._api.getModule('cookie').get(name)
+ elif method=='post': self.autoID = self._api.getModule('request').post1(name)
+ elif method=='get': self.autoID = self._api.getModule('request').get1(name)
+ else: raise 'runtime error: invalid autosession method'
+ self.autoMethod = method
+ self.autoName = name
+ self.autoExpire = expire
+ self.auto = None
+ if self.autoID:
+ self.auto = self.get(self.autoID)
+ if not self.auto: self.autoID = None
+ if not self.autoID: # generate a sessionid
+ self.autoID = self.set(None, self.autoExpire)
+ def _clearAutoSession(self):
+ self.auto = None
+ self.autoID = None
+ self.autoMethod = None
+ self.autoName = None
+ self.autoExpire = None
+
+##################################################
+# Cleanup
+#
+
+# expire sessions every n requests in expectation
+SESSION_EXPIRE_CHECK = 50
+
+class sessionHandlerRegistry:
+ "Registry of all used session handlers."
+ def __init__(self):
+ self.handlers = {}
+ def add(self, handler):
+ self.handlers[handler.getHandlerID()] = handler
+ def list(self):
+ return self.handlers.values()
+ def remove(self, handler):
+ del self.handlers[handler.getHandlerID()]
+
+def sessionCleanup(registry):
+ """Iterates through all session handlers and sessions to perform session
+ cleanup"""
+ if random.randrange(SESSION_EXPIRE_CHECK): return
+ for handler in registry.list():
+ try:
+ sessions = handler.keys()
+ for s in sessions:
+ handler.get(s) # will delete stale sessions
+ except:
+ registry.remove(handler)
+
+
+##################################################
+# Session handlers
+#
+
+class sessionHandler:
+ '''All session handlers should subclass this, and implement the methods
+ marked: 'not implemented'.'''
+ def __init__(self, sessionModule):
+ self.childnum = sessionModule._api.getServerID()
+ def getHandlerID(self):
+ raise 'not implemented'
+ def get(self, id): # method should delete, if session is stale
+ raise 'not implemented'
+ def delete(self, id):
+ raise 'not implemented'
+ def clear(self):
+ raise 'not implemented'
+ def set(self, state, expire, id=None):
+ raise 'not implemented'
+ def keys(self):
+ raise 'not implemented'
+ def __getitem__(self, key):
+ return self.get(key)
+ def __delitem__(self, key):
+ return self.delete(key)
+
+##################################################
+# File-based session handler
+#
+
+class session_dir(sessionHandler):
+ def __init__(self, sessionModule, dir):
+ sessionHandler.__init__(self, sessionModule)
+ if not os.path.exists(dir):
+ raise "session directory '%s' does not exist" % dir
+ self.dir = dir
+ self.prefix = 'spy'
+ self.BINARY_MODE = 1
+ def getHandlerID(self):
+ return 'session_dir', self.childnum, self.dir
+ def get(self, id):
+ if not id: return None
+ filename = os.path.join(self.dir, self.prefix+id)
+ f=None
+ sessionInfo = None
+ try:
+ f=open(filename, 'r')
+ sessionInfo = pickle.load(f)
+ f.close()
+ except:
+ try:
+ if f: f.close()
+ os.unlink(filename)
+ except: pass
+ if sessionInfo:
+ if time.time() > sessionInfo['expire']:
+ self.delete(id)
+ return None
+ else: return sessionInfo['state']
+ else: return None
+ def delete(self, id):
+ try:
+ filename = os.path.join(self.dir, self.prefix+id)
+ os.remove(filename)
+ except: pass
+ def clear(self):
+ for id in self.keys():
+ self.delete(id)
+ def set(self, state, expire, id=None):
+ f=None
+ try:
+ if id:
+ filename = os.path.join(self.dir, self.prefix+id)
+ f=open(filename, 'w')
+ else:
+ filename, f, id = openUniqueFile(self.dir, self.prefix, ('%d_' % self.childnum))
+ sessionInfo = {}
+ sessionInfo['expire'] = int(time.time())+expire
+ sessionInfo['state'] = state
+ pickle.dump(sessionInfo, f, self.BINARY_MODE)
+ f.close()
+ except:
+ try:
+ if f: f.close()
+ except: pass
+ raise
+ return id
+ def keys(self):
+ sessions = os.listdir(self.dir)
+ sessions = filter(lambda s, p=self.prefix: s[:len(p)]==p, sessions)
+ sessions = map(lambda s, self=self: s[len(self.prefix):], sessions)
+ return sessions
+
+# requires unique (dir, prefix)
+def openUniqueFile(dir, prefix, unique, mode='w', max=1000000):
+ filelock = spyceLock.fileLock(os.path.join(dir, prefix))
+ filelock.lock(1)
+ try:
+ id = "%06d"%random.randrange(max)
+ filename = os.path.join(dir, prefix+unique+id)
+ while os.path.exists(filename):
+ id = str(random.randrange(max))
+ filename = os.path.join(dir, prefix+unique+id)
+ f = None
+ f = open(filename, mode)
+ return filename, f, unique+id
+ finally:
+ filelock.unlock()
+
+##################################################
+# Hash file session handlers
+#
+
+class sessionHandlerDBM(sessionHandler):
+ def __init__(self, sessionModule, filename):
+ sessionHandler.__init__(self, sessionModule)
+ self.filename = filename
+ self.dbm = None
+ self.BINARY_MODE = 1
+ self.dbm_type = None # redefine in subclass
+ def getHandlerID(self):
+ return 'session_'+self.dbm_type, self.childnum, self.filename
+ def _open(self):
+ raise 'need to implement'
+ def _close(self):
+ if self.dbm:
+ self.dbm.close()
+ self.dbm = None
+ def get(self, id):
+ if not id: return None
+ self._open()
+ try:
+ expire, state = None, None
+ if self.dbm.has_key(id):
+ expire, state = pickle.loads(self.dbm[id])
+ if expire!=None and time.time() > expire:
+ self.delete(id)
+ state = None
+ return state
+ finally:
+ self._close()
+ def delete(self, id):
+ self._open()
+ try:
+ if self.dbm.has_key(id):
+ del self.dbm[id]
+ finally:
+ self._close()
+ def clear(self):
+ if os.path.exists(self.filename):
+ os.unlink(self.filename)
+ def set(self, state, expire, id=None):
+ self._open()
+ try:
+ if not id:
+ id = generateKey(self.dbm, self.childnum)
+ value = pickle.dumps( (int(time.time())+expire, state), self.BINARY_MODE)
+ self.dbm[id] = value
+ return id
+ finally:
+ self._close()
+ def keys(self):
+ self._open()
+ try:
+ return self.dbm.keys()
+ finally:
+ self._close()
+
+def opendb(dbm_session_handler, module, filename, flags):
+ mod = __import__(module)
+ if not dbm_session_handler.dbm:
+ dbm_session_handler.dbm = mod.open(filename, flags)
+
+class session_gdbm(sessionHandlerDBM):
+ def __init__(self, sessionModule, filename):
+ sessionHandlerDBM.__init__(self, sessionModule, filename)
+ self.dbm_type = 'gdbm'
+ def _open(self):
+ opendb(self, self.dbm_type, self.filename, 'cu')
+
+class session_bsddb(sessionHandlerDBM):
+ def __init__(self, sessionModule, filename):
+ sessionHandlerDBM.__init__(self, sessionModule, filename)
+ self.dbm_type = 'bsddb'
+ def _open(self):
+ opendb(self, 'dbhash', self.filename, 'c')
+
+def generateKey(hash, prefix, max = 1000000):
+ prefix = str(prefix)+'_'
+ key = random.randrange(max)
+ while hash.has_key(prefix+str(key)):
+ key = random.randrange(max)
+ key = prefix+str(key)
+ hash[key] = pickle.dumps(None, 1)
+ return key
+
+
+##################################################
+# User callback session handlers
+#
+
+class session_user(sessionHandler):
+ '''User-callback session handler'''
+ def __init__(self, sessionModule, getf, setf, delf, idsf, info=None):
+ self.serverID = sessionModule._api.getServerID()
+ self.info = info
+ self.getf = getf
+ self.setf = setf
+ self.delf = delf
+ self.idsf = idsf
+ def getHandlerID(self):
+ return 'session_user', self.serverID, self.info
+ def get(self, id): # method should delete, if session is stale
+ return self.getf(self.info, id)
+ def set(self, state, expire, id):
+ return self.setf(self.info, state, expire, self.serverID, id)
+ def delete(self, id):
+ return self.delf(self.info, id)
+ def keys(self):
+ return self.idsf(self.info)
+ def clear(self):
+ for id in self.keys():
+ self.delete(id)
+
+##################################################
+# database-based session handlers
+#
+
+# rimtodo: database-based session handler
+
diff --git a/system/python/spyce/modules/spylambda.py b/system/python/spyce/modules/spylambda.py
new file mode 100644
index 0000000000..60600faa71
--- /dev/null
+++ b/system/python/spyce/modules/spylambda.py
@@ -0,0 +1,55 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+from spyceModule import spyceModule
+import string
+
+__doc__ = """spylambda module produces functions from spyce strings."""
+
+class spylambda(spyceModule):
+ def define(self, sig, code, memoize=0):
+ # compile spyce to cache errors early
+ spycecode = self._api.spyceString((code, sig))
+ if string.strip(sig): sigcomma = sig + ','
+ def processSpyce(args, kwargs, self=self, spycecode=spycecode):
+ s = None
+ try:
+ s = spycecode.newWrapper()
+ modules = self._api.getModules()
+ for name in modules.keys():
+ s.setModule(name, modules[name])
+ s.spyceInit(self._api.getRequest(), self._api.getResponse())
+ result = apply(s.spyceProcess, args, kwargs)
+ finally:
+ if s:
+ s.spyceDestroy()
+ spycecode.returnWrapper(s)
+ return result
+ if memoize:
+ def memoizer(f, id, stdout=self._api.getModule('stdout')):
+ def memoized(args, kwargs, f=f, id=id, stdout=stdout):
+ key = id, `args, kwargs`
+ try: r, s = stdout.memoizeCache[key]
+ except:
+ r, s = stdout.memoizeCache[key] = apply(stdout.capture, (f, args, kwargs))
+ print s
+ return r
+ return memoized
+ processSpyce = memoizer(processSpyce, code)
+ def makeArgProcessor(f):
+ dict = { 'f': f }
+ exec '''
+def processArg(*args, **kwargs):
+ return f(args, kwargs)
+''' in dict
+ return dict['processArg']
+ return makeArgProcessor(processSpyce)
+ def __call__(self, sig, code, memoize=0):
+ return self.define(sig, code)
+ def __repr__(self):
+ return ''
diff --git a/system/python/spyce/modules/stdout.py b/system/python/spyce/modules/stdout.py
new file mode 100644
index 0000000000..c7b7ab7e98
--- /dev/null
+++ b/system/python/spyce/modules/stdout.py
@@ -0,0 +1,104 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+from spyceModule import spyceModule
+from spyceUtil import NoCloseOut
+from cStringIO import StringIO
+
+__doc__ = '''Sets the thread-safe server stdout to the response object for
+convenience of using print statements, and supports output redirection.'''
+
+class stdout(spyceModule):
+ def start(self):
+ # thread-safe stdout swap
+ self.stdout = self._api.getStdout()
+ self._api.setStdout(myResponseWrapper(self))
+ # output redirection stack
+ self.outputStack = []
+ # memoize storage
+ try: self.memoizeCache = self._api.getServerObject().memoized
+ except AttributeError:
+ self.memoizeCache = self._api.getServerObject().memoized = {}
+ def finish(self, theError=None):
+ # close all redirects
+ while self.outputStack:
+ self.pop()
+ # thread-safe stdout swap back
+ self._api.setStdout(self.stdout)
+ def push(self, file=None):
+ 'Redirect stdout to buffer'
+ old_response = self._api.getResponse()
+ old_response_mod = self._api.getModule('response')
+ new_response = spyceCaptureResponse(old_response)
+ self._api.setResponse(new_response)
+ new_response_mod = self._api.spyceModule('response', 'response.py')(self._api)
+ self._api.setModule('response', new_response_mod)
+ new_response_mod.start()
+ self.outputStack.append( (file, old_response, old_response_mod) )
+ def pop(self):
+ 'Return buffer value, and possible write to file'
+ self._api.getModule('response').finish()
+ buffer = self._api.getResponse().getCapturedOutput()
+ file, old_response, old_response_mod = self.outputStack.pop()
+ self._api.setModule('response', old_response_mod)
+ self._api.setResponse(old_response)
+ if file:
+ file = os.path.join(os.path.dirname(self._api.getFilename()), file)
+ out = None
+ try:
+ out = open(file, 'w')
+ out.write(buffer)
+ finally:
+ if out: out.close()
+ return buffer
+ def capture(self, _spyceReserved, *args, **kwargs):
+ 'Capture the output side-effects of a function'
+ f = _spyceReserved # placeholder not to collide with kwargs
+ self.push()
+ r = apply(f, args, kwargs)
+ s = self.pop()
+ return r, s
+ def __repr__(self):
+ return 'depth: %s' % len(self.outputStack)
+
+class myResponseWrapper:
+ def __init__(self, mod):
+ self._mod = mod
+ mod._api.registerModuleCallback(self.syncResponse)
+ self.syncResponse()
+ def syncResponse(self):
+ response = self._mod._api.getModule('response')
+ # functions (for performance)
+ self.write = response.write
+ self.writeln = response.writeln
+ self.flush = response.flush
+ def close(self):
+ raise 'method not allowed'
+
+class spyceCaptureResponse:
+ "Capture output, and let everything else through."
+ def __init__(self, old_response):
+ self._old_response = old_response
+ self._buf = StringIO()
+ def write(self, s):
+ self._buf.write(s)
+ def close(self):
+ raise 'cannot close output while capturing output'
+ def clear(self):
+ self._buf = StringIO()
+ def sendHeaders(self):
+ raise 'cannot sendHeaders while capturing output!'
+ def flush(self, stopFlag=0):
+ pass
+ def unbuffer(self):
+ raise 'cannot unbuffer output while capturing output!'
+ def __getattr__(self, name):
+ return eval('self._old_response.%s'%name)
+ def getCapturedOutput(self):
+ return self._buf.getvalue()
+
diff --git a/system/python/spyce/modules/taglib.py b/system/python/spyce/modules/taglib.py
new file mode 100644
index 0000000000..2631ff16fc
--- /dev/null
+++ b/system/python/spyce/modules/taglib.py
@@ -0,0 +1,102 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+from spyceModule import spyceModule
+import string
+
+__doc__ = '''Spyce tags functionality.'''
+
+class taglib(spyceModule):
+ def start(self):
+ self.context = {}
+ self.stack = []
+ self.taglibs = {}
+ self._api.registerModuleCallback(self.__syncModules)
+ self.__syncModules()
+ def __syncModules(self):
+ modules = self._api.getModules()
+ for name in modules.keys():
+ self.context[name] = modules[name]
+ self.mod_response = modules['response']
+ self.mod_stdout = modules['stdout']
+ def finish(self, theError):
+ self._api.unregisterModuleCallback(self.__syncModules)
+ try:
+ for taglib in self.taglibs.keys():
+ self.unload(taglib)
+ finally:
+ del self.context
+ # load and unload tag libraries
+ def load(self, libname, libfrom=None, libas=None):
+ thename = libname
+ if libas: thename = libas
+ if self.taglibs.has_key(thename):
+ raise 'tag library with that name already loaded'
+ lib = self._api.spyceTaglib(
+ libname, libfrom, self._api.getFilename())(libname)
+ lib.start()
+ self.taglibs[thename] = lib
+ def unload(self, libname):
+ lib = None
+ try:
+ lib = self.taglibs[libname]
+ del self.taglibs[libname]
+ except KeyError: pass
+ if lib: lib.finish()
+ # tag processing
+ def tagPush(self, libname, tagname, attr, pair):
+ try: parent = self.stack[-1]
+ except: parent = None
+ tag = self.taglibs[libname].getTag(tagname, attr, pair, parent)
+ self.stack.append(tag)
+ def tagPop(self):
+ self.outPopCond()
+ if self.stack: self.stack.pop()
+ def getTag(self):
+ return self.stack[-1]
+ def outPush(self):
+ tag = self.stack[-1]
+ if tag.buffer:
+ tag.setBuffered(1)
+ return self.mod_stdout.push()
+ def outPopCond(self):
+ tag = self.stack[-1]
+ if tag.getBuffered():
+ tag.setBuffered(0)
+ return self.mod_stdout.pop()
+ def tagBegin(self):
+ tag = self.getTag()
+ tag.setContext(self.context)
+ tag.setOut(self.mod_response)
+ result = apply(tag.begin, (), tag._attrs)
+ self.outPush()
+ return result
+ def tagBody(self):
+ contents = self.outPopCond()
+ tag = self.getTag()
+ tag.setContext(self.context)
+ tag.setOut(self.mod_response)
+ result = tag.body(contents)
+ if result: self.outPush()
+ return result
+ def tagEnd(self):
+ self.outPopCond()
+ tag = self.getTag()
+ tag.setContext(self.context)
+ tag.setOut(self.mod_response)
+ return tag.end()
+ def tagCatch(self):
+ self.outPopCond()
+ tag = self.getTag()
+ tag.setOut(self.mod_response)
+ tag.catch(sys.exc_info()[0])
+ def __repr__(self):
+ return 'prefixes: %s; stack: %s' % (
+ string.join(self.taglibs.keys(), ', '),
+ string.join(map(lambda x: x.name, self.stack), ', '))
+
diff --git a/system/python/spyce/modules/template.py b/system/python/spyce/modules/template.py
new file mode 100644
index 0000000000..ee7d130e72
--- /dev/null
+++ b/system/python/spyce/modules/template.py
@@ -0,0 +1,68 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+from spyceModule import spyceModule
+import spyceException, spyceCache
+import os
+
+__doc__ = """Template module provides templating functionality: the ability to separate
+form from function, or HTML page design from programming code. This module
+currently provides support for the Cheetah template engine.
+"""
+
+class template(spyceModule):
+ def cheetah(self, filename, lookup=None):
+ "Hook into the Cheetah template engine."
+ # check whether cheetah installed
+ from Cheetah.Compiler import Compiler
+ # define template cache
+ if not self._api.getModule('pool').has_key('cheetahCache'):
+ self._api.getModule('pool')['cheetahCache'] = spyceCache.semanticCache(spyceCache.memoryCache(), cheetahValid, cheetahGenerate)
+ cheetahCache = self._api.getModule('pool')['cheetahCache']
+ # absolute filename, relative to script filename
+ filename = os.path.abspath(os.path.join(
+ os.path.dirname(self._api.getFilename()), filename))
+ # set lookup variables
+ if lookup == None:
+ import inspect
+ lookup = [inspect.currentframe().f_back.f_locals, inspect.currentframe().f_back.f_globals]
+ elif type(lookup)!=type([]):
+ lookup = [lookup]
+ # compile (or get cached) and run template
+ return cheetahCache[filename](searchList=lookup)
+
+##################################################
+# Cheetah semantic cache helper functions
+#
+
+def cheetahValid(filename, validity):
+ try:
+ return os.path.getmtime(filename) == validity
+ except: return 0
+
+def cheetahGenerate(filename):
+ # check permissions
+ if not os.path.exists(filename):
+ raise spyceException.spyceNotFound()
+ if not os.access(filename, os.R_OK):
+ raise spyceException.spyceForbidden()
+ # read the template
+ f = None
+ try:
+ f = open(filename, 'r')
+ buf = f.read()
+ finally:
+ if f: f.close()
+ # compile template, get timestamp
+ mtime = os.path.getmtime(filename)
+ from Cheetah.Compiler import Compiler
+ code = Compiler(source=buf).__str__()
+ dict = {}
+ exec code in dict
+ return mtime, dict['GenTemplate']
+
diff --git a/system/python/spyce/modules/toc.py b/system/python/spyce/modules/toc.py
new file mode 100644
index 0000000000..904f9ca03c
--- /dev/null
+++ b/system/python/spyce/modules/toc.py
@@ -0,0 +1,240 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+from spyceModule import spyceModule
+import tree
+
+__doc__ = '''Table-of-Contents module helps in creating indexed documents NB:
+The TOC module may force two passes of a file, if the first pass TOC emitted
+was not accurate. The second pass occurs via a redirect, so all modules are
+reinitialized. Unfortunately, this breaks things like include.context...'''
+
+ROOT_NAME = 'root'
+
+class toc(spyceModule):
+
+ def start(self):
+ if not self._api.getModule('pool').has_key('toc'):
+ self._api.getModule('pool')['toc'] = {}
+ try:
+ self.oldtree, self.oldtags = self._api.getModule('pool')['toc'][self._api.getFilename()]
+ except (KeyError, TypeError):
+ self.oldtree = tree.tree( (ROOT_NAME, [], None) )
+ self.oldtags = {ROOT_NAME: self.oldtree}
+ # tree data: (tag, numbering, data)
+ self.tree = tree.tree((ROOT_NAME, [], None))
+ self.tags = {ROOT_NAME: self.tree}
+ self.node = self.tree
+ self.numbering = []
+ self.autotag = 0
+ self.tocShown = 0
+ self.fDOC_PUSH = None
+ self.fDOC_POP = None
+ self.fDOC_START = None
+ self.fDOC_END = None
+ self.fTOC_PUSH = None
+ self.fTOC_POP = None
+ self.fTOC_ENTRY = None
+ def finish(self, theError):
+ if not theError:
+ self.tree.computePreChain()
+ regenerate = not (self.oldtree == self.tree)
+ file = self._api.getFilename()
+ self._api.getModule('pool')['toc'][file] = self.tree, self.tags
+ self.oldtree.delete()
+ self.oldtree = None
+ self.oldtags = None
+ if self.tocShown and regenerate:
+ self._api.getModule('redirect').internal(file)
+
+ # set callbacks
+ def setDOC_PUSH(self, f):
+ self.fDOC_PUSH = f
+ def setDOC_POP(self, f):
+ self.fDOC_POP = f
+ def setDOC_START(self, f):
+ self.fDOC_START = f
+ def setDOC_END(self, f):
+ self.fDOC_END = f
+ def setTOC_PUSH(self, f):
+ self.fTOC_PUSH = f
+ def setTOC_POP(self, f):
+ self.fTOC_POP = f
+ def setTOC_ENTRY(self, f):
+ self.fTOC_ENTRY = f
+
+ # sectioning
+ def begin(self, data, tag=None, number=1):
+ self._emit(self.node, self.fDOC_PUSH)
+ self.numbering = _in(self.numbering)
+ if number:
+ self.numbering = _inc(self.numbering)
+ self.node = self.node.append( (tag, self.numbering, data) )
+ else:
+ self.node = self.node.append( (tag, None, data) )
+ if not tag: tag = self._genTag()
+ self.tags[tag] = self.node
+ self._emit(self.node, self.fDOC_START)
+ def end(self):
+ self._emit(self.node, self.fDOC_END)
+ self.numbering = _out(self.numbering)
+ self.node = self.node.parent
+ self._emit(self.node, self.fDOC_POP)
+ def next(self, data, tag=None, number=1):
+ self._emit(self.node, self.fDOC_END)
+ self.node = self.node.parent
+ if number:
+ self.numbering = _inc(self.numbering)
+ self.node = self.node.append( (tag, self.numbering, data) )
+ else:
+ self.node = self.node.append( (tag, None, data) )
+ if not tag: tag = self._genTag()
+ self.tags[tag] = self.node
+ self._emit(self.node, self.fDOC_START)
+ def anchor(self, data, tag=ROOT_NAME):
+ self.tree.data = tag, [], data
+ self.tags[tag] = self.tree
+
+ # shortcuts
+ b=begin
+ e=end
+ n=next
+
+ # sectioning by depth
+ def level(self, depth, data, tag=None):
+ curdepth = self.getDepth()
+ if curdepth > depth: # indent
+ while curdepth > depth:
+ self.end()
+ curdepth = self.getDepth()
+ self.next(data, tag)
+ elif curdepth < depth: # outdent
+ while curdepth < depth - 1:
+ self.begin(None)
+ curdepth = self.getDepth()
+ self.begin(data, tag)
+ else: # next
+ self.next(data, tag)
+ def l1(self, data, tag=None):
+ self.level(1, data, tag)
+ def l2(self, data, tag=None):
+ self.level(2, data, tag)
+ def l3(self, data, tag=None):
+ self.level(3, data, tag)
+ def l4(self, data, tag=None):
+ self.level(4, data, tag)
+ def l5(self, data, tag=None):
+ self.level(5, data, tag)
+ def l6(self, data, tag=None):
+ self.level(6, data, tag)
+ def l7(self, data, tag=None):
+ self.level(7, data, tag)
+ def l8(self, data, tag=None):
+ self.level(8, data, tag)
+ def l9(self, data, tag=None):
+ self.level(9, data, tag)
+
+ # show toc
+ def showTOC(self):
+ self.tocShown = 1
+ self._tocHelper(self.oldtree)
+ def _tocHelper(self, node):
+ self._emit(node, self.fTOC_ENTRY)
+ if node.children:
+ self._emit(node, self.fTOC_PUSH)
+ for c in node.children:
+ self._tocHelper(c)
+ self._emit(node, self.fTOC_POP)
+
+ # current state
+ def getTag(self, node=None):
+ self.tocShown = 1
+ if not node: node = self.node
+ tag, numbering, data = node.data
+ return tag
+ def getNumbering(self, tag=None):
+ self.tocShown = 1
+ try:
+ node = self.node
+ if tag: node = self.oldtags[tag]
+ tag, numbering, data = node.data
+ return numbering
+ except KeyError:
+ return None
+ def getData(self, tag=None):
+ self.tocShown = 1
+ try:
+ node = self.node
+ if tag: node = self.oldtags[tag]
+ tag, numbering, data = node.data
+ return data
+ except KeyError:
+ return None
+ def getDepth(self, tag=None):
+ self.tocShown = 1
+ try:
+ node = self.node
+ if tag: node = self.tags[tag]
+ return node.depth
+ except KeyError:
+ return None
+ def getNextTag(self, tag=None):
+ self.tocShown = 1
+ try:
+ if not tag: tag = self.getTag()
+ tag = self.oldtags[tag].next
+ if tag==None: return None
+ return self.getTag(tag)
+ except KeyError:
+ return None
+ def getPrevTag(self, tag=None):
+ self.tocShown = 1
+ try:
+ if not tag: tag = self.getTag()
+ node = self.oldtags[tag].prev
+ if node==None: return None
+ return self.getTag(node)
+ except KeyError:
+ return None
+ def getParentTag(self, tag=None):
+ self.tocShown = 1
+ try:
+ if not tag: tag = self.getTag()
+ node = self.oldtags[tag].parent
+ if node==None: return None
+ return self.getTag(node)
+ except KeyError:
+ return None
+ def getChildrenTags(self, tag=None):
+ self.tocShown = 1
+ try:
+ if not tag: tag = self.getTag()
+ nodes = self.oldtags[tag].children
+ return map(self.getTag, nodes)
+ except KeyError:
+ return None
+
+ # internal helpers
+ def _genTag(self):
+ tag = 'auto_'+str(self.autotag)
+ self.autotag = self.autotag + 1
+ return tag
+ def _emit(self, node, f):
+ tag, numbering, data = node.data
+ if f: s = f(node.depth, tag, numbering, data)
+
+# hierarchical counting
+def _inc(numbering, inc=1):
+ return numbering[:-1]+[numbering[-1]+inc]
+def _in(numbering, start=0):
+ return numbering+[start]
+def _out(numbering):
+ return numbering[:-1]
+
+def defaultOutput(tag, numbering, data):
+ return reduce(lambda s, i: '%s%d.' % (s, i), numbering, '') + ' ' + str(data)
diff --git a/system/python/spyce/modules/transform.py b/system/python/spyce/modules/transform.py
new file mode 100644
index 0000000000..1ca4f62a42
--- /dev/null
+++ b/system/python/spyce/modules/transform.py
@@ -0,0 +1,155 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+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): '&quot;', chr(38): '&amp;', chr(60): '&lt;', chr(62): '&gt;',
+ chr(160): '&nbsp;', chr(161): '&iexcl;', chr(162): '&cent;', chr(163): '&pound;',
+ chr(164): '&curren;', chr(165): '&yen;', chr(166): '&brvbar;', chr(167): '&sect;',
+ chr(168): '&uml;', chr(169): '&copy;', chr(170): '&ordf;', chr(171): '&laquo;',
+ chr(172): '&not;', chr(173): '&shy;', chr(174): '&reg;', chr(175): '&macr;',
+ chr(176): '&deg;', chr(177): '&plusmn;', chr(178): '&sup2;', chr(179): '&sup3;',
+ chr(180): '&acute;', chr(181): '&micro;', chr(182): '&para;', chr(183): '&middot;',
+ chr(184): '&cedil;', chr(185): '&sup1;', chr(186): '&ordm;', chr(187): '&raquo;',
+ chr(188): '&frac14;', chr(189): '&frac12;', chr(190): '&frac34;', chr(191): '&iquest;',
+ chr(192): '&Agrave;', chr(193): '&Aacute;', chr(194): '&Acirc;', chr(195): '&Atilde;',
+ chr(196): '&Auml;', chr(197): '&Aring;', chr(198): '&AElig;', chr(199): '&Ccedil;',
+ chr(200): '&Egrave;', chr(201): '&Eacute;', chr(202): '&Ecirc;', chr(203): '&Euml;',
+ chr(204): '&Igrave;', chr(205): '&Iacute;', chr(206): '&Icirc;', chr(207): '&Iuml;',
+ chr(208): '&ETH;', chr(209): '&Ntilde;', chr(210): '&Ograve;', chr(211): '&Oacute;',
+ chr(212): '&Ocirc;', chr(213): '&Otilde;', chr(214): '&Ouml;', chr(215): '&times;',
+ chr(216): '&Oslash;', chr(217): '&Ugrave;', chr(218): '&Uacute;', chr(219): '&Ucirc;',
+ chr(220): '&Uuml;', chr(221): '&Yacute;', chr(222): '&THORN;', chr(223): '&szlig;',
+ chr(224): '&agrave;', chr(225): '&aacute;', chr(226): '&acirc;', chr(227): '&atilde;',
+ chr(228): '&auml;', chr(229): '&aring;', chr(230): '&aelig;', chr(231): '&ccedil;',
+ chr(232): '&egrave;', chr(233): '&eacute;', chr(234): '&ecirc;', chr(235): '&euml;',
+ chr(236): '&igrave;', chr(237): '&iacute;', chr(238): '&icirc;', chr(239): '&iuml;',
+ chr(240): '&eth;', chr(241): '&ntilde;', chr(242): '&ograve;', chr(243): '&oacute;',
+ chr(244): '&ocirc;', chr(245): '&otilde;', chr(246): '&ouml;', chr(247): '&divide;',
+ chr(248): '&oslash;', chr(249): '&ugrave;', chr(250): '&uacute;', chr(251): '&ucirc;',
+ chr(252): '&uuml;', chr(253): '&yacute;', chr(254): '&thorn;', chr(255): '&yuml;',
+}
+_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: '&nbsp;', str(o))
diff --git a/system/python/spyce/run_spyceCGI.py b/system/python/spyce/run_spyceCGI.py
new file mode 100755
index 0000000000..fe7fb4832a
--- /dev/null
+++ b/system/python/spyce/run_spyceCGI.py
@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+__doc__ = '''Version checking spyceCGI.py wrapper.'''
+
+script = 'spyceCGI.py'
+
+import sys, os, verchk
+
+if __name__ == '__main__':
+ spycePath = os.path.abspath(os.path.dirname(sys.modules['verchk'].__file__))
+ sys.argv[0] = os.path.join(spycePath, script)
+ sys.argv.insert(0, os.path.join(spycePath, 'verchk.py'))
+ execfile(sys.argv[0])
diff --git a/system/python/spyce/run_spyceCmd.py b/system/python/spyce/run_spyceCmd.py
new file mode 100755
index 0000000000..ddf248ab00
--- /dev/null
+++ b/system/python/spyce/run_spyceCmd.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+__doc__ = '''Version checking spyceCmd.py wrapper.'''
+
+script = 'spyceCmd.py'
+
+import sys, os, verchk
+
+if __name__ == '__main__':
+ spycePath = os.path.abspath(os.path.dirname(sys.modules['verchk'].__file__))
+ sys.argv[0] = os.path.join(spycePath, script)
+ sys.argv.insert(0, os.path.join(spycePath, 'verchk.py'))
+ execfile(sys.argv[0])
+
diff --git a/system/python/spyce/run_spyceModpy.py b/system/python/spyce/run_spyceModpy.py
new file mode 100755
index 0000000000..5a1cd4348e
--- /dev/null
+++ b/system/python/spyce/run_spyceModpy.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+__doc__ = '''Version checking spyceModpy.py wrapper.'''
+
+try:
+ import _apache
+ from mod_python import apache
+except: pass
+
+def spyceMain(apacheRequest):
+ return spyceMainVersion(apacheRequest)
+
+def spyceMainVersion(apacheRequest):
+ "Version checking Apache entry point."
+ import verchk
+ if not verchk.checkversion(verchk.REQUIRED):
+ import sys
+ apacheRequest.content_type = 'text/plain'
+ apacheRequest.send_http_header()
+ apacheRequest.write('Spyce can not run on this version of Python.\n')
+ apacheRequest.write('Python version '+sys.version[:3]+' detected.\n')
+ apacheRequest.write('Python version '+verchk.REQUIRED+' or greater required.\n')
+ try:
+ return apache.OK
+ except: pass
+ else:
+ global spyceMain
+ import spyceModpy
+ spyceMain = spyceModpy.spyceMain
+ return spyceModpy.spyceMain(apacheRequest)
+
+if __name__ == '__main__':
+ print "********** ERROR: **********"
+ print "This program can not be run from the command-line."
+ print "Use run_spyceCmd.py, or run via Apache."
+ print "For configuring Apache, have a look at 'spyceApache.conf'."
+ print
+ print "Also, please read the documentation at:"
+ print " http://spyce.sourceforge.net"
+ print "for other options."
+
diff --git a/system/python/spyce/spyce.conf b/system/python/spyce/spyce.conf
new file mode 100644
index 0000000000..7b65e178c7
--- /dev/null
+++ b/system/python/spyce/spyce.conf
@@ -0,0 +1,162 @@
+###############
+#
+# Spyce configuration file
+# -- an example
+#
+###############
+
+
+
+###############
+#
+# The [spyce] section defines the main spyce configuration options
+#
+
+[spyce]
+
+#
+# The spyce path determines which directories are searched for when
+# loading modules and tag libraries. The Spyce installation directory
+# is always searched first. Any directories in the SPYCE_PATH
+# environment are also searched.
+#
+
+path: Q:\python\spyce
+
+
+#
+# The import option can be used to pre-load various Python modules
+# during engine initialization.
+#
+
+# import: myModule, myModule2
+
+
+#
+# The error option sets the server-level error handler; file-level
+# error handling is defined within Spyce scripts using the error
+# module. The format of this option is MODULE:FUNCTION. The server
+# will call the error handler as:
+# MODULE.FUNCTION(request, response, error)
+# if a server-level error should occur.
+#
+
+#error: error:serverHandler
+
+
+#
+# The pageerror option sets the default page-level error handler.
+# The format of this option is one of:
+# string:MODULE:VARIABLE
+# file:FILE
+# where the lowercase words are literals.
+#
+
+#pageerror: string:error:defaultErrorTemplate
+
+
+#
+# The concurrency option is used for long-lived engines (i.e. not for
+# CGI or command-line processing), and sets the concurrency level for
+# the engine. Legal values are 'thread' (or 'threading') and 'fork'
+# (or 'forking'). Any other value will result in serial request
+# processing, which also is the default.
+#
+
+concurrency: thread
+#concurrency: fork
+
+
+#
+# The cache option affects the underlying cache mechanism that the
+# server uses to maintain compiled Spyce scripts. The general format
+# for this option is TYPE:INFO, where TYPE defines the cache handler
+# and INFO is specific to that cache handler. Currently, Spyce
+# supports two cache handlers:
+# - memory: the default, takes no parameters
+# - file: store compiled Spyce scripts to files on disk in some
+# directory; the INFO is the directory to use
+#
+
+#cache: file:Q:\python\temp\
+
+
+#
+# The debug option affects the caching of compiled Spyce files and
+# Spyce modules. When it is turned on, then caching is disabled. It
+# should NOT be used in a production environment, as compilation is
+# not a optimized (fast) process. The values '0', 'off' or 'false'
+# disable debugging. Any other value turns it on. The default, if
+# omitted is off.
+#
+
+#debug: 1
+
+
+
+###############
+#
+# The globals section defines server-wide constants. The values can be
+# arbitrary Python expressions. These values are evaluated and stored
+# in a hashtable under the given option name. The hashtable is
+# accessible as "pool.globals" within any Spyce file (with the pool
+# method loaded), or as self.wrapper.server.globals within any Spyce
+# module.
+#
+
+[globals]
+
+#name: "My Website"
+#four: 2+2
+
+
+
+###############
+#
+# The www section defines options for the built-in Spyce web server.
+#
+
+[www]
+
+#
+# The root option defines the document root of the webserver from
+# which all requests are processed. This option can be overridden from
+# the command-line. The default is the current directory when the
+# server is started.
+#
+
+root: Q:\web
+
+
+#
+# The port option defines which TCP port the server will listen on.
+# The default is port 80.
+#
+
+#port: 8000
+
+
+#
+# The mime option is a comma-separated list of files. The files should
+# be definitions of mime-types for common file extensions in the
+# standard Apache format. The default is to read the spyce.mime file
+# in Spyce installation directory.
+#
+
+#mime: /etc/mime.types
+
+
+#
+# The ext_ and ext_foo options define the default handler and the
+# handler used for files ending in .foo, respectively. The currently
+# supported handlers are:
+# spyce - process the file at the requested path a spyce script
+# dump - transfer the file at the requested path verbatim,
+# providing an appropriate "Content-type" header, if it is known.
+# By default, all .spy files are processed via the spyce handler, and
+# all others through the dump handler.
+#
+
+#ext_html: spyce
+#ext_: spyce
+
diff --git a/system/python/spyce/spyce.mime b/system/python/spyce/spyce.mime
new file mode 100644
index 0000000000..b9e5a936f3
--- /dev/null
+++ b/system/python/spyce/spyce.mime
@@ -0,0 +1,495 @@
+# This is the mime.types file from the Apache web server distribution (1.3.22)
+# with local modifications.
+
+# This file controls what Internet media types are sent to the client for
+# given file extension(s). Sending the correct media type to the client
+# is important so they know how to handle the content of the file.
+# Extra types can either be added here or by using an AddType directive
+# in your config files. For more information about Internet media types,
+# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type
+# registry is at <ftp://ftp.iana.org/in-notes/iana/assignments/media-types/>.
+
+# MIME type Extension
+application/EDI-Consent
+application/EDI-X12
+application/EDIFACT
+application/activemessage
+application/andrew-inset ez
+application/applefile
+application/atomicmail
+application/batch-SMTP
+application/beep+xml
+application/cals-1840
+application/commonground
+application/cybercash
+application/dca-rft
+application/dec-dx
+application/dvcs
+application/eshop
+application/http
+application/hyperstudio
+application/iges
+application/index
+application/index.cmd
+application/index.obj
+application/index.response
+application/index.vnd
+application/iotp
+application/ipp
+application/isup
+application/font-tdpfr
+application/mac-binhex40 hqx
+application/mac-compactpro cpt
+application/macwriteii
+application/marc
+application/mathematica
+application/mathematica-old
+application/msword doc
+application/news-message-id
+application/news-transmission
+application/ocsp-request
+application/ocsp-response
+application/octet-stream bin dms lha lzh exe class so dll
+application/oda oda
+application/parityfec
+application/pdf pdf
+application/pgp-encrypted
+application/pgp-keys
+application/pgp-signature
+application/pkcs10
+application/pkcs7-mime
+application/pkcs7-signature
+application/pkix-cert
+application/pkix-crl
+application/pkixcmp
+application/postscript ai eps ps
+application/prs.alvestrand.titrax-sheet
+application/prs.cww
+application/prs.nprend
+application/qsig
+application/remote-printing
+application/riscos
+application/rtf rtf
+application/set-payment
+application/set-payment-initiation
+application/set-registration
+application/set-registration-initiation
+application/sgml
+application/sgml-open-catalog
+application/sieve
+application/slate
+application/timestamp-query
+application/timestamp-reply
+application/vemmi
+application/vnd.3M.Post-it-Notes
+application/vnd.FloGraphIt
+application/vnd.accpac.simply.aso
+application/vnd.accpac.simply.imp
+application/vnd.acucobol
+application/vnd.aether.imp
+application/vnd.anser-web-certificate-issue-initiation
+application/vnd.anser-web-funds-transfer-initiation
+application/vnd.audiograph
+application/vnd.businessobjects
+application/vnd.bmi
+application/vnd.canon-cpdl
+application/vnd.canon-lips
+application/vnd.claymore
+application/vnd.commerce-battelle
+application/vnd.commonspace
+application/vnd.comsocaller
+application/vnd.contact.cmsg
+application/vnd.cosmocaller
+application/vnd.cups-postscript
+application/vnd.cups-raster
+application/vnd.cups-raw
+application/vnd.ctc-posml
+application/vnd.cybank
+application/vnd.dna
+application/vnd.dpgraph
+application/vnd.dxr
+application/vnd.ecdis-update
+application/vnd.ecowin.chart
+application/vnd.ecowin.filerequest
+application/vnd.ecowin.fileupdate
+application/vnd.ecowin.series
+application/vnd.ecowin.seriesrequest
+application/vnd.ecowin.seriesupdate
+application/vnd.enliven
+application/vnd.epson.esf
+application/vnd.epson.msf
+application/vnd.epson.quickanime
+application/vnd.epson.salt
+application/vnd.epson.ssf
+application/vnd.ericsson.quickcall
+application/vnd.eudora.data
+application/vnd.fdf
+application/vnd.ffsns
+application/vnd.framemaker
+application/vnd.fsc.weblaunch
+application/vnd.fujitsu.oasys
+application/vnd.fujitsu.oasys2
+application/vnd.fujitsu.oasys3
+application/vnd.fujitsu.oasysgp
+application/vnd.fujitsu.oasysprs
+application/vnd.fujixerox.ddd
+application/vnd.fujixerox.docuworks
+application/vnd.fujixerox.docuworks.binder
+application/vnd.fut-misnet
+application/vnd.grafeq
+application/vnd.groove-account
+application/vnd.groove-identity-message
+application/vnd.groove-injector
+application/vnd.groove-tool-message
+application/vnd.groove-tool-template
+application/vnd.groove-vcard
+application/vnd.hhe.lesson-player
+application/vnd.hp-HPGL
+application/vnd.hp-PCL
+application/vnd.hp-PCLXL
+application/vnd.hp-hpid
+application/vnd.hp-hps
+application/vnd.httphone
+application/vnd.hzn-3d-crossword
+application/vnd.ibm.afplinedata
+application/vnd.ibm.MiniPay
+application/vnd.ibm.modcap
+application/vnd.informix-visionary
+application/vnd.intercon.formnet
+application/vnd.intertrust.digibox
+application/vnd.intertrust.nncp
+application/vnd.intu.qbo
+application/vnd.intu.qfx
+application/vnd.irepository.package+xml
+application/vnd.is-xpr
+application/vnd.japannet-directory-service
+application/vnd.japannet-jpnstore-wakeup
+application/vnd.japannet-payment-wakeup
+application/vnd.japannet-registration
+application/vnd.japannet-registration-wakeup
+application/vnd.japannet-setstore-wakeup
+application/vnd.japannet-verification
+application/vnd.japannet-verification-wakeup
+application/vnd.koan
+application/vnd.lotus-1-2-3
+application/vnd.lotus-approach
+application/vnd.lotus-freelance
+application/vnd.lotus-notes
+application/vnd.lotus-organizer
+application/vnd.lotus-screencam
+application/vnd.lotus-wordpro
+application/vnd.mcd
+application/vnd.mediastation.cdkey
+application/vnd.meridian-slingshot
+application/vnd.mif mif
+application/vnd.minisoft-hp3000-save
+application/vnd.mitsubishi.misty-guard.trustweb
+application/vnd.mobius.daf
+application/vnd.mobius.dis
+application/vnd.mobius.msl
+application/vnd.mobius.plc
+application/vnd.mobius.txf
+application/vnd.motorola.flexsuite
+application/vnd.motorola.flexsuite.adsi
+application/vnd.motorola.flexsuite.fis
+application/vnd.motorola.flexsuite.gotap
+application/vnd.motorola.flexsuite.kmr
+application/vnd.motorola.flexsuite.ttc
+application/vnd.motorola.flexsuite.wem
+application/vnd.mozilla.xul+xml
+application/vnd.ms-artgalry
+application/vnd.ms-asf
+application/vnd.ms-excel xls
+application/vnd.ms-lrm
+application/vnd.ms-powerpoint ppt
+application/vnd.ms-project
+application/vnd.ms-tnef
+application/vnd.ms-works
+application/vnd.mseq
+application/vnd.msign
+application/vnd.music-niff
+application/vnd.musician
+application/vnd.netfpx
+application/vnd.noblenet-directory
+application/vnd.noblenet-sealer
+application/vnd.noblenet-web
+application/vnd.novadigm.EDM
+application/vnd.novadigm.EDX
+application/vnd.novadigm.EXT
+application/vnd.osa.netdeploy
+application/vnd.palm
+application/vnd.pg.format
+application/vnd.pg.osasli
+application/vnd.powerbuilder6
+application/vnd.powerbuilder6-s
+application/vnd.powerbuilder7
+application/vnd.powerbuilder7-s
+application/vnd.powerbuilder75
+application/vnd.powerbuilder75-s
+application/vnd.previewsystems.box
+application/vnd.publishare-delta-tree
+application/vnd.pvi.ptid1
+application/vnd.pwg-xhtml-print+xml
+application/vnd.rapid
+application/vnd.s3sms
+application/vnd.seemail
+application/vnd.shana.informed.formdata
+application/vnd.shana.informed.formtemplate
+application/vnd.shana.informed.interchange
+application/vnd.shana.informed.package
+application/vnd.sss-cod
+application/vnd.sss-dtf
+application/vnd.sss-ntf
+application/vnd.street-stream
+application/vnd.svd
+application/vnd.swiftview-ics
+application/vnd.triscape.mxs
+application/vnd.trueapp
+application/vnd.truedoc
+application/vnd.tve-trigger
+application/vnd.ufdl
+application/vnd.uplanet.alert
+application/vnd.uplanet.alert-wbxml
+application/vnd.uplanet.bearer-choice-wbxml
+application/vnd.uplanet.bearer-choice
+application/vnd.uplanet.cacheop
+application/vnd.uplanet.cacheop-wbxml
+application/vnd.uplanet.channel
+application/vnd.uplanet.channel-wbxml
+application/vnd.uplanet.list
+application/vnd.uplanet.list-wbxml
+application/vnd.uplanet.listcmd
+application/vnd.uplanet.listcmd-wbxml
+application/vnd.uplanet.signal
+application/vnd.vcx
+application/vnd.vectorworks
+application/vnd.vidsoft.vidconference
+application/vnd.visio
+application/vnd.vividence.scriptfile
+application/vnd.wap.sic sic
+application/vnd.wap.slc slc
+application/vnd.wap.wbxml wbxml
+application/vnd.wap.wmlc wmlc
+application/vnd.wap.wmlscriptc wmlsc
+application/vnd.webturbo
+application/vnd.wrq-hp3000-labelled
+application/vnd.wt.stf
+application/vnd.xara
+application/vnd.xfdl
+application/vnd.yellowriver-custom-menu
+application/whoispp-query
+application/whoispp-response
+application/wita
+application/wordperfect5.1
+application/x-bcpio bcpio
+application/x-bzip2 bz2
+application/x-cdlink vcd
+application/x-chess-pgn pgn
+application/x-compress
+application/x-cpio cpio
+application/x-csh csh
+application/x-director dcr dir dxr
+application/x-dvi dvi
+application/x-futuresplash spl
+application/x-gtar gtar
+application/x-gzip gz tgz
+application/x-hdf hdf
+application/x-javascript js
+application/x-kword kwd kwt
+application/x-kspread ksp
+application/x-kpresenter kpr kpt
+application/x-kchart chrt
+application/x-killustrator kil
+application/x-koan skp skd skt skm
+application/x-latex latex
+application/x-netcdf nc cdf
+application/x-ogg ogg
+
+application/x-rpm rpm
+
+application/x-sh sh
+application/x-shar shar
+application/x-shockwave-flash swf
+application/x-stuffit sit
+application/x-sv4cpio sv4cpio
+application/x-sv4crc sv4crc
+application/x-tar tar
+application/x-tcl tcl
+application/x-tex tex
+application/x-texinfo texinfo texi
+application/x-troff t tr roff
+application/x-troff-man man
+application/x-troff-me me
+application/x-troff-ms ms
+application/x-ustar ustar
+application/x-wais-source src
+application/x400-bp
+application/xhtml+xml xhtml xht
+application/xml
+application/xml-dtd
+application/xml-external-parsed-entity
+application/zip zip
+audio/32kadpcm
+audio/g.722.1
+audio/l16
+audio/midi mid midi kar
+audio/mp4a-latm
+audio/mpa-robust
+audio/mpeg mpga mp2 mp3
+audio/parityfec
+audio/prs.sid
+audio/telephone-event
+audio/tone
+audio/vnd.cisco.nse
+audio/vnd.cns.anp1
+audio/vnd.cns.inf1
+audio/vnd.digital-winds
+audio/vnd.everad.plj
+audio/vnd.lucent.voice
+audio/vnd.nortel.vbk
+audio/vnd.nuera.ecelp4800
+audio/vnd.nuera.ecelp7470
+audio/vnd.nuera.ecelp9600
+audio/vnd.octel.sbc
+audio/vnd.qcelp
+audio/vnd.rhetorex.32kadpcm
+audio/vnd.vmx.cvsd
+audio/x-mpegurl m3u
+audio/x-realaudio ra
+chemical/x-pdb pdb
+chemical/x-xyz xyz
+image/bmp bmp
+image/cgm
+image/g3fax
+image/gif gif
+image/ief ief
+image/jpeg jpeg jpg jpe
+image/naplps
+image/png png
+image/prs.btif
+image/prs.pti
+image/tiff tiff tif
+image/vnd.cns.inf2
+image/vnd.djvu djvu djv
+image/vnd.dwg
+image/vnd.dxf
+image/vnd.fastbidsheet
+image/vnd.fpx
+image/vnd.fst
+image/vnd.fujixerox.edmics-mmr
+image/vnd.fujixerox.edmics-rlc
+image/vnd.mix
+image/vnd.net-fpx
+image/vnd.svf
+image/vnd.wap.wbmp wbmp
+image/vnd.xiff
+image/x-cmu-raster ras
+image/x-portable-anymap pnm
+image/x-portable-bitmap pbm
+image/x-portable-graymap pgm
+image/x-portable-pixmap ppm
+image/x-rgb rgb
+image/x-xbitmap xbm
+image/x-xpixmap xpm
+image/x-xwindowdump xwd
+message/delivery-status
+message/disposition-notification
+message/external-body
+message/http
+message/news
+message/partial
+message/rfc822
+message/s-http
+model/iges igs iges
+model/mesh msh mesh silo
+model/vnd.dwf
+model/vnd.flatland.3dml
+model/vnd.gdl
+model/vnd.gs-gdl
+model/vnd.gtw
+model/vnd.mts
+model/vnd.vtu
+model/vrml wrl vrml
+multipart/alternative
+multipart/appledouble
+multipart/byteranges
+multipart/digest
+multipart/encrypted
+multipart/form-data
+multipart/header-set
+multipart/mixed
+multipart/parallel
+multipart/related
+multipart/report
+multipart/signed
+multipart/voice-message
+text/calendar
+text/css css
+text/directory
+text/enriched
+text/parityfec
+text/plain asc txt
+text/prs.lines.tag
+text/rfc822-headers
+text/richtext rtx
+text/rtf rtf
+text/sgml sgml sgm
+text/tab-separated-values tsv
+text/t140
+text/uri-list
+text/vnd.DMClientScript
+text/vnd.IPTC.NITF
+text/vnd.IPTC.NewsML
+text/vnd.abc
+text/vnd.curl
+text/vnd.flatland.3dml
+text/vnd.fly
+text/vnd.fmi.flexstor
+text/vnd.in3d.3dml
+text/vnd.in3d.spot
+text/vnd.latex-z
+text/vnd.motorola.reflex
+text/vnd.ms-mediapackage
+text/vnd.wap.si si
+text/vnd.wap.sl sl
+text/vnd.wap.wml wml
+text/vnd.wap.wmlscript wmls
+text/x-setext etx
+text/xml xml xsl
+text/xml-external-parsed-entity
+video/mp4v-es
+video/mpeg mpeg mpg mpe
+video/parityfec
+video/pointer
+video/quicktime qt mov
+video/vnd.fvt
+video/vnd.motorola.video
+video/vnd.motorola.videop
+video/vnd.mpegurl mxu
+video/vnd.mts
+video/vnd.nokia.interleaved-multimedia
+video/vnd.vivo
+video/x-msvideo avi
+video/x-sgi-movie movie
+x-conference/x-cooltalk ice
+audio/x-pn-realaudio rmm ram
+audio/vnd.rn-realaudio ra
+application/smil smi smil
+text/vnd.rn-realtext rt
+video/vnd.rn-realvideo rv
+image/vnd.rn-realflash rf swf
+application/x-shockwave-flash2-preview rf swf
+application/sdp sdp
+application/x-sdp sdp
+application/vnd.rn-realmedia rm
+image/vnd.rn-realpix rp
+audio/wav wav
+audio/x-wav wav
+audio/x-pn-wav wav
+audio/x-pn-windows-acm wav
+audio/basic au
+audio/x-pn-au au
+audio/aiff aiff af
+audio/x-aiff aiff af
+audio/x-pn-aiff aiff af
+text/html html htm
diff --git a/system/python/spyce/spyce.nsi b/system/python/spyce/spyce.nsi
new file mode 100644
index 0000000000..fd7a4d674d
--- /dev/null
+++ b/system/python/spyce/spyce.nsi
@@ -0,0 +1,208 @@
+; spyce.nsi
+; Spyce Installer (NSIS script)
+
+;#####################################
+;VERSION
+
+!define VERSION 1.3.13
+!define RELEASE 1
+
+;#####################################
+;DEFINES
+
+!define NAME Spyce
+!define NAME_SMALL spyce
+!define Desc "Spyce - Python Server Pages"
+!define REG_PROG "SOFTWARE\${NAME}"
+!define REG_UNINST "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}"
+!define PYTHON "python.exe"
+!define REG_PYTHONLOC "${REG_PROG}"
+
+!define COMPILE 1
+
+;#####################################
+;OPTIONS
+
+OutFile "${NAME_SMALL}-${VERSION}.exe"
+InstallDir $PROGRAMFILES\${NAME_SMALL}
+InstallDirRegKey HKLM ${REG_PROG} "location"
+
+Name "${NAME}"
+Caption "${NAME} Windows Installer"
+UninstallCaption "${NAME} Windows Uninstaller"
+DirText "${NAME} Windows Installer"
+ComponentText "${NAME} Windows Installer"
+CompletedText "${NAME} Windows Installer is finished"
+UninstallText "${NAME} Windows Uninstaller"
+BrandingText " "
+
+CRCCheck on
+AutoCloseWindow true
+EnabledBitmap misc/one-check.bmp
+DisabledBitmap misc/one-nocheck.bmp
+ShowInstDetails show
+ShowUninstDetails show
+;BGGradient
+SilentUnInstall silent
+Icon misc\pics\spyce-border.ico ; MUST contain a 32x32x16 color icon
+UninstallIcon misc\pics\spyce-border.ico
+WindowIcon on
+SetOverwrite on
+SetCompress auto
+SetDatablockOptimize on
+SetDateSave off
+
+;#####################################
+;SECTIONS
+
+Section "${NAME} engine"
+ ReadRegStr $9 HKLM ${REG_PYTHONLOC} "python"
+ SetOutPath $INSTDIR
+ ; create and register uninstaller
+ WriteUninstaller "uninstall.exe"
+ WriteRegStr HKLM ${REG_PROG} "location" "$INSTDIR"
+ WriteRegStr HKLM "${REG_UNINST}" "DisplayName" "${NAME}: ${DESC} (remove only)"
+ WriteRegStr HKLM "${REG_UNINST}" "UninstallString" '"$INSTDIR\uninstall.exe"'
+
+ ; copy spyce engine files
+ File *.py
+ File CHANGES LICENCE README THANKS spyceApache.conf spyce.conf.eg misc\pics\spyce.ico spyce.mime
+ SetOutPath "$INSTDIR\modules"
+ File modules\*.py
+ SetOutPath "$INSTDIR\tags"
+ File tags\*.py
+ SetOutPath -
+ ; pre-compile the sources
+ !ifdef COMPILE
+ DetailPrint "Compile Spyce sources."
+ ExecWait `"$9" "$INSTDIR\spyceParser.py"`
+ ExecWait `"$9" "$INSTDIR\installHelper.py" "--py=$INSTDIR"`
+ ;ExecWait `"$9" -OO "$INSTDIR\installHelper.py" "--py=$INSTDIR"`
+ ExecWait `"$9" "$INSTDIR\installHelper.py" "--py=$INSTDIR\modules"`
+ ;ExecWait `"$9" -OO "$INSTDIR\installHelper.py" "--py=$INSTDIR\modules"`
+ ExecWait `"$9" "$INSTDIR\installHelper.py" "--py=$INSTDIR\tags"`
+ ;ExecWait `"$9" -OO "$INSTDIR\installHelper.py" "--py=$INSTDIR\tags"`
+ !endif
+SectionEnd
+
+Section "${NAME} documentation"
+ SectionIn RO
+ ReadRegStr $9 HKLM ${REG_PYTHONLOC} "python"
+ ; copy Spyce documentation files
+ SetOutPath "$INSTDIR\docs"
+ File docs\*.spy docs\*.gif
+ SetOutPath "$INSTDIR\docs\examples"
+ File docs\examples\*.spy docs\examples\*.spi docs\examples\*.tmpl docs\examples\*.py docs\examples\*.gif
+ SetOutPath "$INSTDIR\docs\inc"
+ File docs\inc\*.spi
+ SetOutPath -
+ ; compile documentation
+ !ifdef COMPILE
+ DetailPrint "Compile Spyce documentation."
+ ExecWait `"$9" "$INSTDIR\run_spyceCmd.py" "-O" "$INSTDIR\docs\*.spy"`
+ !endif
+SectionEnd
+
+SectionDivider "Options"
+
+Section "Create start menu shortcuts"
+ CreateDirectory "$SMPROGRAMS\${NAME}"
+ CreateShortCut "$SMPROGRAMS\${NAME}\Spyce Documentation.lnk" "$INSTDIR\docs\index.html" "" "$INSTDIR\spyce.ico"
+ CreateShortCut "$SMPROGRAMS\${NAME}\Spyce Documentation -- localhost.lnk" "http://localhost/spyce/" "" ""
+ CreateShortCut "$SMPROGRAMS\${NAME}\Spyce Online.lnk" "http://spyce.sf.net/" "" ""
+ CreateShortCut "$SMPROGRAMS\${NAME}\Spyce Examples.lnk" "$INSTDIR\docs\examples" "" "$INSTDIR\spyce.ico"
+ CreateShortCut "$SMPROGRAMS\${NAME}\Uninstall Spyce.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
+SectionEnd
+
+Section "Create shell extensions"
+ WriteRegStr HKCR ".spy" "" "SpyceFile"
+ WriteRegStr HKCR "SpyceFile" "" "Spyce dynamic HTML file"
+ WriteRegStr HKCR "SpyceFile\DefaultIcon" "" $INSTDIR\spyce.ico,0
+ WriteRegStr HKCR "SpyceFile\shell\open\command" "" 'notepad.exe "%1"'
+ WriteRegStr HKCR "SpyceFile\shell\compile" "" "Compile Spyce"
+ WriteRegStr HKCR "SpyceFile\shell\compile\command" "" '"$9" "$INSTDIR\run_spyceCmd.py" -O "%1"'
+ WriteRegStr HKCR "SpyceFile\shell" "" "compile"
+SectionEnd
+
+Section "Configure Apache"
+ DetailPrint "Configuring Apache..."
+ ExecWait `"$9" "$INSTDIR\installHelper.py" "--apache=$INSTDIR"`
+ ExecWait `"$9" "$INSTDIR\installHelper.py" "--apacheRestart"`
+ MessageBox MB_OK|MB_ICONEXCLAMATION "$\nApache reconfigured and restarted.$\nIf everything is ok, you should be able to browse to: http://localhost/spyce/$\nIf not, please check your httpd.conf file and/or restart Apache."
+
+SectionEnd
+
+
+Section "Uninstall"
+ ReadRegStr $9 HKLM ${REG_PYTHONLOC} "python"
+ DetailPrint "Unconfiguring Apache..."
+ ExecWait `"$9" "$INSTDIR\installHelper.py" "--apacheUN"`
+ ExecWait `"$9" "$INSTDIR\installHelper.py" "--apacheRestart"`
+ RMDir /r "$INSTDIR"
+ RMDir /r "$SMPROGRAMS\${NAME}"
+ DeleteRegKey HKLM ${REG_UNINST}
+ DeleteRegKey HKLM ${REG_PROG}
+ DeleteRegKey HKCR ".spy"
+ DeleteRegKey HKCR "SpyceFile"
+SectionEnd
+
+;#####################################
+;FUNCTIONS
+
+Function detectPython
+ ; see if there is any python interpreter
+ ClearErrors
+ ExecShell "open" "${PYTHON}" `-c "print 'Python is alive!'"` SW_SHOWMINIMIZED
+ IfErrors 0 NoAbort
+ MessageBox MB_OK|MB_ICONEXCLAMATION "Unable to find Python interpreter. Please install Python first."
+ Abort
+ NoAbort:
+ ; find out where it is
+ GetTempFileName $9
+ GetTempFileName $8
+ FileOpen $7 $9 w
+ FileWrite $7 'import sys$\n'
+ FileWrite $7 "f=open(r'$8', 'w')$\n"
+ FileWrite $7 'f.write(sys.executable)$\n'
+ FileWrite $7 'f.close()$\n'
+ FileClose $7
+ ExecShell "open" "${PYTHON}" `"$9"` SW_SHOWMINIMIZED
+ IntOp $0 0 + 0
+ Loop:
+ FileOpen $7 $8 r
+ FileRead $7 $6
+ FileClose $7
+ StrCmp $6 "" 0 EndLoop
+ Sleep 100
+ IntOp $0 $0 + 1
+ IntCmp $0 50 EndLoop
+ Goto Loop
+ EndLoop:
+ Delete $9
+ StrCpy $9 "$6" ; put the python path in $9 -- GLOBAL
+ StrCmp $9 "" 0 NoAbort2
+ MessageBox MB_OK|MB_ICONEXCLAMATION "Mechanism for discovering Python path via sys.executable did not work.$\nSorry, but automatic installation is unable to proceed. Please contact the author."
+ Abort
+ NoAbort2:
+ WriteRegStr HKLM ${REG_PYTHONLOC} "python" "$9"
+FunctionEnd
+
+Function .onInit
+ Call detectPython
+FunctionEnd
+
+Function .onInstSuccess
+ DetailPrint "Spyce successfully installed."
+ MessageBox MB_OK "Spyce successfully installed."
+ ExecShell "open" "$INSTDIR\docs\index.html" SW_SHOWMAXIMIZED
+FunctionEnd
+
+Function un.onInit
+ MessageBox MB_YESNO|MB_ICONQUESTION "Are you sure that you want to uninstall Spyce?" IDYES NoAbort
+ Abort
+ NoAbort:
+FunctionEnd
+
+Function un.onUninstSuccess
+ MessageBox MB_OK "Spyce successfully uninstalled."
+FunctionEnd
diff --git a/system/python/spyce/spyce.nsi.in b/system/python/spyce/spyce.nsi.in
new file mode 100644
index 0000000000..1005f7a59e
--- /dev/null
+++ b/system/python/spyce/spyce.nsi.in
@@ -0,0 +1,208 @@
+; spyce.nsi
+; Spyce Installer (NSIS script)
+
+;#####################################
+;VERSION
+
+!define VERSION __VERSION__
+!define RELEASE __RELEASE__
+
+;#####################################
+;DEFINES
+
+!define NAME Spyce
+!define NAME_SMALL spyce
+!define Desc "Spyce - Python Server Pages"
+!define REG_PROG "SOFTWARE\${NAME}"
+!define REG_UNINST "Software\Microsoft\Windows\CurrentVersion\Uninstall\${NAME}"
+!define PYTHON "python.exe"
+!define REG_PYTHONLOC "${REG_PROG}"
+
+!define COMPILE 1
+
+;#####################################
+;OPTIONS
+
+OutFile "${NAME_SMALL}-${VERSION}.exe"
+InstallDir $PROGRAMFILES\${NAME_SMALL}
+InstallDirRegKey HKLM ${REG_PROG} "location"
+
+Name "${NAME}"
+Caption "${NAME} Windows Installer"
+UninstallCaption "${NAME} Windows Uninstaller"
+DirText "${NAME} Windows Installer"
+ComponentText "${NAME} Windows Installer"
+CompletedText "${NAME} Windows Installer is finished"
+UninstallText "${NAME} Windows Uninstaller"
+BrandingText " "
+
+CRCCheck on
+AutoCloseWindow true
+EnabledBitmap misc/one-check.bmp
+DisabledBitmap misc/one-nocheck.bmp
+ShowInstDetails show
+ShowUninstDetails show
+;BGGradient
+SilentUnInstall silent
+Icon misc\pics\spyce-border.ico ; MUST contain a 32x32x16 color icon
+UninstallIcon misc\pics\spyce-border.ico
+WindowIcon on
+SetOverwrite on
+SetCompress auto
+SetDatablockOptimize on
+SetDateSave off
+
+;#####################################
+;SECTIONS
+
+Section "${NAME} engine"
+ ReadRegStr $9 HKLM ${REG_PYTHONLOC} "python"
+ SetOutPath $INSTDIR
+ ; create and register uninstaller
+ WriteUninstaller "uninstall.exe"
+ WriteRegStr HKLM ${REG_PROG} "location" "$INSTDIR"
+ WriteRegStr HKLM "${REG_UNINST}" "DisplayName" "${NAME}: ${DESC} (remove only)"
+ WriteRegStr HKLM "${REG_UNINST}" "UninstallString" '"$INSTDIR\uninstall.exe"'
+
+ ; copy spyce engine files
+ File *.py
+ File CHANGES LICENCE README THANKS spyceApache.conf spyce.conf.eg misc\pics\spyce.ico spyce.mime
+ SetOutPath "$INSTDIR\modules"
+ File modules\*.py
+ SetOutPath "$INSTDIR\tags"
+ File tags\*.py
+ SetOutPath -
+ ; pre-compile the sources
+ !ifdef COMPILE
+ DetailPrint "Compile Spyce sources."
+ ExecWait `"$9" "$INSTDIR\spyceParser.py"`
+ ExecWait `"$9" "$INSTDIR\installHelper.py" "--py=$INSTDIR"`
+ ;ExecWait `"$9" -OO "$INSTDIR\installHelper.py" "--py=$INSTDIR"`
+ ExecWait `"$9" "$INSTDIR\installHelper.py" "--py=$INSTDIR\modules"`
+ ;ExecWait `"$9" -OO "$INSTDIR\installHelper.py" "--py=$INSTDIR\modules"`
+ ExecWait `"$9" "$INSTDIR\installHelper.py" "--py=$INSTDIR\tags"`
+ ;ExecWait `"$9" -OO "$INSTDIR\installHelper.py" "--py=$INSTDIR\tags"`
+ !endif
+SectionEnd
+
+Section "${NAME} documentation"
+ SectionIn RO
+ ReadRegStr $9 HKLM ${REG_PYTHONLOC} "python"
+ ; copy Spyce documentation files
+ SetOutPath "$INSTDIR\docs"
+ File docs\*.spy docs\*.gif
+ SetOutPath "$INSTDIR\docs\examples"
+ File docs\examples\*.spy docs\examples\*.spi docs\examples\*.tmpl docs\examples\*.py docs\examples\*.gif
+ SetOutPath "$INSTDIR\docs\inc"
+ File docs\inc\*.spi
+ SetOutPath -
+ ; compile documentation
+ !ifdef COMPILE
+ DetailPrint "Compile Spyce documentation."
+ ExecWait `"$9" "$INSTDIR\run_spyceCmd.py" "-O" "$INSTDIR\docs\*.spy"`
+ !endif
+SectionEnd
+
+SectionDivider "Options"
+
+Section "Create start menu shortcuts"
+ CreateDirectory "$SMPROGRAMS\${NAME}"
+ CreateShortCut "$SMPROGRAMS\${NAME}\Spyce Documentation.lnk" "$INSTDIR\docs\index.html" "" "$INSTDIR\spyce.ico"
+ CreateShortCut "$SMPROGRAMS\${NAME}\Spyce Documentation -- localhost.lnk" "http://localhost/spyce/" "" ""
+ CreateShortCut "$SMPROGRAMS\${NAME}\Spyce Online.lnk" "http://spyce.sf.net/" "" ""
+ CreateShortCut "$SMPROGRAMS\${NAME}\Spyce Examples.lnk" "$INSTDIR\docs\examples" "" "$INSTDIR\spyce.ico"
+ CreateShortCut "$SMPROGRAMS\${NAME}\Uninstall Spyce.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
+SectionEnd
+
+Section "Create shell extensions"
+ WriteRegStr HKCR ".spy" "" "SpyceFile"
+ WriteRegStr HKCR "SpyceFile" "" "Spyce dynamic HTML file"
+ WriteRegStr HKCR "SpyceFile\DefaultIcon" "" $INSTDIR\spyce.ico,0
+ WriteRegStr HKCR "SpyceFile\shell\open\command" "" 'notepad.exe "%1"'
+ WriteRegStr HKCR "SpyceFile\shell\compile" "" "Compile Spyce"
+ WriteRegStr HKCR "SpyceFile\shell\compile\command" "" '"$9" "$INSTDIR\run_spyceCmd.py" -O "%1"'
+ WriteRegStr HKCR "SpyceFile\shell" "" "compile"
+SectionEnd
+
+Section "Configure Apache"
+ DetailPrint "Configuring Apache..."
+ ExecWait `"$9" "$INSTDIR\installHelper.py" "--apache=$INSTDIR"`
+ ExecWait `"$9" "$INSTDIR\installHelper.py" "--apacheRestart"`
+ MessageBox MB_OK|MB_ICONEXCLAMATION "$\nApache reconfigured and restarted.$\nIf everything is ok, you should be able to browse to: http://localhost/spyce/$\nIf not, please check your httpd.conf file and/or restart Apache."
+
+SectionEnd
+
+
+Section "Uninstall"
+ ReadRegStr $9 HKLM ${REG_PYTHONLOC} "python"
+ DetailPrint "Unconfiguring Apache..."
+ ExecWait `"$9" "$INSTDIR\installHelper.py" "--apacheUN"`
+ ExecWait `"$9" "$INSTDIR\installHelper.py" "--apacheRestart"`
+ RMDir /r "$INSTDIR"
+ RMDir /r "$SMPROGRAMS\${NAME}"
+ DeleteRegKey HKLM ${REG_UNINST}
+ DeleteRegKey HKLM ${REG_PROG}
+ DeleteRegKey HKCR ".spy"
+ DeleteRegKey HKCR "SpyceFile"
+SectionEnd
+
+;#####################################
+;FUNCTIONS
+
+Function detectPython
+ ; see if there is any python interpreter
+ ClearErrors
+ ExecShell "open" "${PYTHON}" `-c "print 'Python is alive!'"` SW_SHOWMINIMIZED
+ IfErrors 0 NoAbort
+ MessageBox MB_OK|MB_ICONEXCLAMATION "Unable to find Python interpreter. Please install Python first."
+ Abort
+ NoAbort:
+ ; find out where it is
+ GetTempFileName $9
+ GetTempFileName $8
+ FileOpen $7 $9 w
+ FileWrite $7 'import sys$\n'
+ FileWrite $7 "f=open(r'$8', 'w')$\n"
+ FileWrite $7 'f.write(sys.executable)$\n'
+ FileWrite $7 'f.close()$\n'
+ FileClose $7
+ ExecShell "open" "${PYTHON}" `"$9"` SW_SHOWMINIMIZED
+ IntOp $0 0 + 0
+ Loop:
+ FileOpen $7 $8 r
+ FileRead $7 $6
+ FileClose $7
+ StrCmp $6 "" 0 EndLoop
+ Sleep 100
+ IntOp $0 $0 + 1
+ IntCmp $0 50 EndLoop
+ Goto Loop
+ EndLoop:
+ Delete $9
+ StrCpy $9 "$6" ; put the python path in $9 -- GLOBAL
+ StrCmp $9 "" 0 NoAbort2
+ MessageBox MB_OK|MB_ICONEXCLAMATION "Mechanism for discovering Python path via sys.executable did not work.$\nSorry, but automatic installation is unable to proceed. Please contact the author."
+ Abort
+ NoAbort2:
+ WriteRegStr HKLM ${REG_PYTHONLOC} "python" "$9"
+FunctionEnd
+
+Function .onInit
+ Call detectPython
+FunctionEnd
+
+Function .onInstSuccess
+ DetailPrint "Spyce successfully installed."
+ MessageBox MB_OK "Spyce successfully installed."
+ ExecShell "open" "$INSTDIR\docs\index.html" SW_SHOWMAXIMIZED
+FunctionEnd
+
+Function un.onInit
+ MessageBox MB_YESNO|MB_ICONQUESTION "Are you sure that you want to uninstall Spyce?" IDYES NoAbort
+ Abort
+ NoAbort:
+FunctionEnd
+
+Function un.onUninstSuccess
+ MessageBox MB_OK "Spyce successfully uninstalled."
+FunctionEnd
diff --git a/system/python/spyce/spyce.py b/system/python/spyce/spyce.py
new file mode 100755
index 0000000000..3a21f36d16
--- /dev/null
+++ b/system/python/spyce/spyce.py
@@ -0,0 +1,674 @@
+#!/usr/bin/env python
+
+__version__ = '1.3.13'
+__release__ = '1'
+
+DEBUG_ERROR = 0
+
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to LICENCE for legalese
+#
+# Name: spyce
+# Author: Rimon Barr <rimon-AT-acm.org>
+# Start date: 8 April 2002
+# Purpose: Python Server Pages
+# WWW: http://spyce.sourceforge.net/
+# CVS: $Id$
+##################################################
+
+# note: doc string used in documentation: doc/index.spy
+__doc__ = '''SPYCE is a server-side language that supports simple and
+efficient Python-based dynamic HTML generation, otherwise called <i>Python
+Server Pages</i> (PSP). Those who are familiar with JSP, PHP, or ASP and like
+Python, should have a look at Spyce. Its modular design makes it very flexible
+and extensible. It can also be used as a command-line utility for static text
+pre-processing or as a web-server proxy.'''
+
+import sys, os, copy, string, imp
+import spyceConfig, spyceCompile, spyceException
+import spyceModule, spyceTag
+import spyceLock, spyceCache, spyceUtil
+
+##################################################
+# Spyce engine globals
+#
+
+# spyceServer object - one per engine instance
+SPYCE_SERVER = None
+def getServer(
+ config_file=None,
+ overide_www_port=None,
+ overide_www_root=None,
+ force=0):
+ global SPYCE_SERVER
+ if force or not SPYCE_SERVER:
+ SPYCE_SERVER = spyceServer(
+ config_file=config_file,
+ overide_www_root=overide_www_root,
+ overide_www_port=overide_www_port,
+ )
+ return SPYCE_SERVER
+
+SPYCE_GLOBALS = None
+def getServerGlobals():
+ global SPYCE_GLOBALS
+ return SPYCE_GLOBALS
+
+SPYCE_LOADER = 'spyceLoader'
+SPYCE_ENTRY = 'SPYCE_ENTRY'
+DEFAULT_MODULES = ('request', 'response', 'stdout', 'error')
+
+##################################################
+# Spyce core objects
+#
+
+class spyceServerObject:
+ "serverObject placeholder"
+ pass
+
+class spyceServer:
+ "One per server, stored in SPYCE_SERVER (above) at processing of first request."
+ def __init__(self,
+ config_file=None,
+ overide_www_root=None,
+ overide_www_port=None,
+ ):
+ global SPYCE_GLOBALS
+ # server object
+ self.serverobject = spyceServerObject()
+ # http headers
+ try: self.entry = os.environ[SPYCE_ENTRY]
+ except: self.entry = 'UNKNOWN'
+ self.spyceHeader = 'Spyce/%s_%s Python/%s' % (self.entry, str(__version__), sys.version[:3])
+ # configuration dictionary
+ self.config = spyceConfig.spyceConfig(
+ file=config_file,
+ overide_www_root=overide_www_root,
+ overide_www_port=overide_www_port,
+ )
+ # server globals/constants
+ self.globals = self.config.getSpyceGlobals()
+ SPYCE_GLOBALS = self.globals # hack
+ # now finish processing config file; this way imported modules have
+ # access to the globals
+ self.config.process ()
+ # spyce module search path
+ self.path = self.config.getSpycePath()
+ # concurrency mode
+ self.concurrency = self.config.getSpyceConcurrency()
+ # imports
+ self.imports = self.config.getSpyceImport()
+ # debug mode
+ self.debug = self.config.getSpyceDebug()
+ # spyce cache
+ type, info = self.config.getSpyceCache()
+ if type in ('file',):
+ type = spyceCache.fileCache(info)
+ elif type in ('mem', 'memory'):
+ type = spyceCache.memoryCache(info)
+ else: type = spyceCache.memoryCache()
+ if self.debug: type = None
+ self.spyce_cache = spyceCache.semanticCache(type, spyceCacheValid, spyceCacheGenerate)
+ # spyce module cache
+ self.module_cache = {}
+ if self.debug:
+ self.module_cache = None
+ # page error handler
+ pageerror = self.config.getSpycePageError()
+ if pageerror[0]=='string':
+ pageerror = pageerror[0], self.loadModule(pageerror[2], pageerror[1]+'.py')
+ self.pageerror = pageerror
+ # engine error handler
+ error = self.config.getSpyceError()
+ self.error = self.loadModule(error[1], error[0]+'.py')
+ # spyce thread-safe stdout object
+ if self.concurrency == spyceConfig.SPYCE_CONCURRENCY_THREAD:
+ self.stdout = spyceUtil.ThreadedWriter(sys.stdout)
+ self.lock = spyceLock.threadLock()
+ sys.stdout = self.stdout
+ else:
+ self.stdout = None
+ self.lock = spyceLock.dummyLock()
+ # set sys.stdout
+ def loadModule(self, name, file=None, rel_file=None):
+ "Find and load a module, with caching"
+ if not file: file=name+'.py'
+ key = name, file, rel_file
+ if self.module_cache!=None:
+ try: return self.module_cache[key]
+ except: pass # cache miss
+ def loadModuleHelper(file=file, rel_file=rel_file, path=self.path):
+ if rel_file: path = path + [os.path.dirname(rel_file)]
+ for p in path:
+ f=None
+ try:
+ p = os.path.join(p, file)
+ if os.path.exists(p) and os.access(p, os.R_OK):
+ f = open(p, 'r')
+ return imp.load_source(SPYCE_LOADER, p, f)
+ finally:
+ if f: f.close()
+ raise 'unable to find module "%s" in path: %s' % (file, path)
+ # load and cache module
+ dict = {'loadModuleHelper': loadModuleHelper}
+ exec 'foo = loadModuleHelper()' in dict
+ mod = eval('dict["foo"].%s' % name)
+ if self.module_cache!=None:
+ self.module_cache[key] = mod
+ return mod
+ def fileHandler(self, request, response, filename, sig='', args=None, kwargs=None):
+ return self.commonHandler(request, response, ('file', (filename, sig)), args, kwargs)
+ def stringHandler(self, request, response, code, sig='', args=None, kwargs=None):
+ return self.commonHandler(request, response, ('string', (code, sig)), args, kwargs)
+ def commonHandler(self, request, response, spyceInfo, args=None, kwargs=None):
+ "Handle a request. This method is NOT thread safe."
+ try:
+ thespyce = theError = None
+ try:
+ spycecode = self.spyce_cache[spyceInfo]
+ thespyce = spycecode.newWrapper()
+ response.addHeader('X-Spyce', self.spyceHeader, 1)
+ try:
+ thespyce.spyceInit(request, response)
+ if args==None: args=[]
+ if kwargs==None: kwargs={}
+ apply(thespyce.spyceProcess, args, kwargs)
+ except spyceException.spyceRuntimeException, theError: pass
+ finally:
+ if DEBUG_ERROR and theError:
+ sys.stderr.write(`theError`+'\n')
+ if thespyce:
+ thespyce.spyceDestroy(theError)
+ spycecode.returnWrapper(thespyce)
+ except spyceException.spyceDone: pass
+ except spyceException.spyceRedirect, e:
+ return spyceFileHandler(request, response, e.filename)
+ except KeyboardInterrupt: raise
+ except (spyceException.spyceNotFound, spyceException.spyceForbidden,
+ spyceException.spyceSyntaxError, spyceException.pythonSyntaxError,
+ SyntaxError), e:
+ return self.error(self, request, response, e)
+ except SystemExit: pass
+ except:
+ errorString = spyceUtil.exceptionString()
+ try:
+ import cgi
+ response.clear()
+ response.write('<html><pre>\n')
+ response.write('Unexpected exception: (please report!)\n')
+ response.write(cgi.escape(errorString))
+ response.write('\n</pre></html>\n')
+ response.returncode = response.RETURN_OK
+ except:
+ sys.stderr.write(errorString+'\n')
+ return response.returncode
+
+class spyceRequest:
+ """Underlying Spyce request object. All implementations (CGI, Apache...)
+ should subclass and implement the methods marked 'not implemented'."""
+ def __init__(self):
+ self._in = None
+ def read(self, limit=None):
+ if limit:
+ return self._in.read(limit)
+ else:
+ return self._in.read()
+ def readline(self, limit=None):
+ if limit:
+ return self._in.readline(limit)
+ else:
+ return self._in.readline()
+ def env(self, name=None):
+ raise 'not implemented'
+ def getHeader(self, type=None):
+ raise 'not implemented'
+ def getServerID(self):
+ raise 'not implemented'
+
+class spyceResponse:
+ """Underlying Spyce response object. All implementations (CGI, Apache...)
+ should subclass and implement the methods marked 'not implemented', and
+ also properly define the RETURN codes."""
+ RETURN_CONTINUE = 100
+ RETURN_SWITCHING_PROTOCOLS = 101
+ RETURN_OK = 200
+ RETURN_CREATED = 201
+ RETURN_ACCEPTED = 202
+ RETURN_NON_AUTHORITATIVE_INFORMATION = 203
+ RETURN_NO_CONTENT = 204
+ RETURN_RESET_CONTENT = 205
+ RETURN_PARTIAL_CONTENT = 206
+ RETURN_MULTIPLE_CHOICES = 300
+ RETURN_MOVED_PERMANENTLY = 301
+ RETURN_MOVED_TEMPORARILY = 302
+ RETURN_SEE_OTHER = 303
+ RETURN_NOT_MODIFIED = 304
+ RETURN_USE_PROXY = 305
+ RETURN_TEMPORARY_REDIRECT = 307
+ RETURN_BAD_REQUEST = 400
+ RETURN_UNAUTHORIZED = 401
+ RETURN_PAYMENT_REQUIRED = 402
+ RETURN_FORBIDDEN = 403
+ RETURN_NOT_FOUND = 404
+ RETURN_METHOD_NOT_ALLOWED = 405
+ RETURN_NOT_ACCEPTABLE = 406
+ RETURN_PROXY_AUTHENTICATION_REQUIRED = 407
+ RETURN_REQUEST_TIMEOUT = 408
+ RETURN_CONFLICT = 409
+ RETURN_GONE = 410
+ RETURN_LENGTH_REQUIRED = 411
+ RETURN_PRECONDITION_FAILED = 412
+ RETURN_REQUEST_ENTITY_TOO_LARGE = 413
+ RETURN_REQUEST_URI_TOO_LONG = 414
+ RETURN_UNSUPPORTED_MEDIA_TYPE = 415
+ RETURN_REQUEST_RANGE_NOT_SATISFIABLE = 416
+ RETURN_EXPECTATION_FAILED = 417
+ RETURN_INTERNAL_SERVER_ERROR = 500
+ RETURN_NOT_IMPLEMENTED = 501
+ RETURN_BAD_GATEWAY = 502
+ RETURN_SERVICE_UNAVAILABLE = 503
+ RETURN_GATEWAY_TIMEOUT = 504
+ RETURN_HTTP_VERSION_NOT_SUPPORTED = 505
+ RETURN_CODE = {
+ RETURN_CONTINUE: 'CONTINUE',
+ RETURN_SWITCHING_PROTOCOLS: 'SWITCHING PROTOCOLS',
+ RETURN_OK: 'OK',
+ RETURN_CREATED: 'CREATED',
+ RETURN_ACCEPTED: 'ACCEPTED',
+ RETURN_NON_AUTHORITATIVE_INFORMATION: 'NON AUTHORITATIVE INFORMATION',
+ RETURN_NO_CONTENT: 'NO CONTENT',
+ RETURN_RESET_CONTENT: 'RESET CONTENT',
+ RETURN_PARTIAL_CONTENT: 'PARTIAL CONTENT',
+ RETURN_MULTIPLE_CHOICES: 'MULTIPLE CHOICES',
+ RETURN_MOVED_PERMANENTLY: 'MOVED PERMANENTLY',
+ RETURN_MOVED_TEMPORARILY: 'MOVED TEMPORARILY',
+ RETURN_SEE_OTHER: 'SEE OTHER',
+ RETURN_NOT_MODIFIED: 'NOT MODIFIED',
+ RETURN_USE_PROXY: 'USE PROXY',
+ RETURN_TEMPORARY_REDIRECT: 'TEMPORARY REDIRECT',
+ RETURN_BAD_REQUEST: 'BAD REQUEST',
+ RETURN_UNAUTHORIZED: 'UNAUTHORIZED',
+ RETURN_PAYMENT_REQUIRED: 'PAYMENT REQUIRED',
+ RETURN_FORBIDDEN: 'FORBIDDEN',
+ RETURN_NOT_FOUND: 'NOT FOUND',
+ RETURN_METHOD_NOT_ALLOWED: 'METHOD NOT ALLOWED',
+ RETURN_NOT_ACCEPTABLE: 'NOT ACCEPTABLE',
+ RETURN_PROXY_AUTHENTICATION_REQUIRED: 'PROXY AUTHENTICATION REQUIRED',
+ RETURN_REQUEST_TIMEOUT: 'REQUEST TIMEOUT',
+ RETURN_CONFLICT: 'CONFLICT',
+ RETURN_GONE: 'GONE',
+ RETURN_LENGTH_REQUIRED: 'LENGTH REQUIRED',
+ RETURN_PRECONDITION_FAILED: 'PRECONDITION FAILED',
+ RETURN_REQUEST_ENTITY_TOO_LARGE: 'REQUEST ENTITY TOO LARGE',
+ RETURN_REQUEST_URI_TOO_LONG: 'REQUEST URI TOO LONG',
+ RETURN_UNSUPPORTED_MEDIA_TYPE: 'UNSUPPORTED MEDIA TYPE',
+ RETURN_REQUEST_RANGE_NOT_SATISFIABLE: 'REQUEST RANGE NOT SATISFIABLE',
+ RETURN_EXPECTATION_FAILED: 'EXPECTATION FAILED',
+ RETURN_INTERNAL_SERVER_ERROR: 'INTERNAL SERVER ERROR',
+ RETURN_NOT_IMPLEMENTED: 'NOT IMPLEMENTED',
+ RETURN_BAD_GATEWAY: 'BAD GATEWAY',
+ RETURN_SERVICE_UNAVAILABLE: 'SERVICE UNAVAILABLE',
+ RETURN_GATEWAY_TIMEOUT: 'GATEWAY TIMEOUT',
+ RETURN_HTTP_VERSION_NOT_SUPPORTED: 'HTTP VERSION NOT SUPPORTED',
+ }
+ def __init__(self):
+ pass
+ def write(self, s):
+ raise 'not implemented'
+ def writeErr(self, s):
+ raise 'not implemented'
+ def close(self):
+ raise 'not implemented'
+ def clear(self):
+ raise 'not implemented'
+ def sendHeaders(self):
+ raise 'not implemented'
+ def clearHeaders(self):
+ raise 'not implemented'
+ def setContentType(self, content_type):
+ raise 'not implemented'
+ def setReturnCode(self, code):
+ raise 'not implemented'
+ def addHeader(self, type, data, replace=0):
+ raise 'not implemented'
+ def flush(self):
+ raise 'not implemented'
+ def unbuffer(self):
+ raise 'not implemented'
+
+class spyceCode:
+ '''Takes care of compiling the Spyce file, and generating a wrapper'''
+ def __init__(self, code, filename=None, sig='', limit=3):
+ # store variables
+ self._filename = filename
+ self._limit = limit
+ # generate code
+ self._code, self._coderefs, self._modrefs = \
+ spyceCompile.spyceCompile(code, filename, sig, getServer())
+ self._wrapperQueue = []
+ self._wrappersMade = 0
+ # wrappers
+ def newWrapper(self):
+ "Get a wrapper for this code from queue, or make new one"
+ try: return self._wrapperQueue.pop()
+ except IndexError: pass
+ self._wrappersMade = self._wrappersMade + 1
+ return spyceWrapper(self)
+ def returnWrapper(self, w):
+ "Return wrapper back to queue after use"
+ if len(self._wrapperQueue)<self._limit:
+ self._wrapperQueue.append(w)
+ # serialization
+ def __getstate__(self):
+ return self._filename, self._code, self._coderefs, self._modrefs, self._limit
+ def __setstate__(self, state):
+ self._filename, self._code, self._coderefs, self._modrefs, self._limit = state
+ self._wrapperQueue = []
+ self._wrappersMade = 0
+ # accessors
+ def getCode(self):
+ "Return processed Spyce (i.e. Python) code"
+ return self._code
+ def getFilename(self):
+ "Return source filename, if it exists"
+ return self._filename
+ def getCodeRefs(self):
+ "Return python-to-Spyce code line references"
+ return self._coderefs
+ def getModRefs(self):
+ "Return list of import references in Spyce code"
+ return self._modrefs
+
+class spyceWrapper:
+ """Wrapper object runs the entire show, bringing together the code, the
+ Spyce environment, the request and response objects and the modules. It is
+ NOT thread safe - new instances are generated as necessary by spyceCode!
+ This object is generated by a spyceCode object. The common Spyce handler
+ code calls the 'processing' functions. Module writers interact with this
+ object via the spyceModuleAPI calls. This is arguable the trickiest portion
+ of the Spyce so don't touch unless you know what you are doing."""
+ def __init__(self, spycecode):
+ # store variables
+ self._spycecode = spycecode
+ # api object
+ self._api = self
+ # module tracking
+ self._modCache = {}
+ self._modstarted = []
+ self._modules = {}
+ # compile python code
+ self._codeenv = { spyceCompile.SPYCE_WRAPPER: self._api }
+ try: exec self._spycecode.getCode() in self._codeenv
+ except SyntaxError: raise spyceException.pythonSyntaxError(self)
+ self._freshenv = self._codeenv.keys()
+ # spyce hooks
+ noop = lambda *args: None
+ self.process = self._codeenv[spyceCompile.SPYCE_PROCESS_FUNC]
+ try: self.init = self._codeenv[spyceCompile.SPYCE_INIT_FUNC]
+ except: self.init = noop
+ try: self.destroy = self._codeenv[spyceCompile.SPYCE_DESTROY_FUNC]
+ except: self.destroy = noop
+ # request, response
+ self._response = self._request = None
+ self._responseCallback = {}
+ self._moduleCallback = {}
+ def _startModule(self, name, file=None, as=None, force=0):
+ "Initialise module for current request."
+ if as==None: as=name
+ if force or not self._codeenv.has_key(as):
+ modclass = getServer().loadModule(name, file, self._spycecode.getFilename())
+ mod = modclass(self._api)
+ self.setModule(as, mod, 0)
+ if DEBUG_ERROR:
+ sys.stderr.write(as+'.start\n')
+ mod.start()
+ self._modstarted.append((as, mod))
+ else: mod = self._codeenv[as]
+ return mod
+ # spyce processing
+ def spyceInit(self, request, response):
+ "Initialise a Spyce for processing."
+ self._request = request
+ self._response = response
+ for mod in DEFAULT_MODULES:
+ self._startModule(mod)
+ self._modstarteddefault = self._modstarted
+ self._modstarted = []
+ for (modname, modfrom, modas) in self.getModRefs():
+ self._startModule(modname, modfrom, modas, 1)
+ exec '_spyce_start()' in { '_spyce_start': self.init }
+ def spyceProcess(self, *args, **kwargs):
+ "Process the current Spyce request."
+ path = sys.path
+ try:
+ if self._spycecode.getFilename():
+ path = copy.copy(sys.path)
+ sys.path.append(os.path.dirname(self._spycecode.getFilename()))
+ dict = { '_spyce_process': self.process,
+ '_spyce_args': args, '_spyce_kwargs': kwargs, }
+ exec '_spyce_result = apply(_spyce_process, _spyce_args, _spyce_kwargs)' in dict
+ return dict['_spyce_result']
+ finally:
+ sys.path = path
+ def spyceDestroy(self, theError=None):
+ "Cleanup after the request processing."
+ try:
+ exec '_spyce_finish()' in { '_spyce_finish': self.destroy }
+ # explicit modules
+ self._modstarted.reverse()
+ for as, mod in self._modstarted:
+ try:
+ if DEBUG_ERROR:
+ sys.stderr.write(as+'.finish\n')
+ mod.finish(theError)
+ except spyceException.spyceDone: pass
+ except spyceException.spyceRedirect, e:
+ return spyceFileHandler(self._request, self._response, e.filename)
+ except KeyboardInterrupt: raise
+ except SystemExit: pass
+ except: theError = spyceException.spyceRuntimeException(self._api)
+ finishError = None
+ # default modules
+ self._modstarteddefault.reverse()
+ for as, mod in self._modstarteddefault:
+ try:
+ if DEBUG_ERROR:
+ sys.stderr.write(as+'.finish\n')
+ mod.finish(theError)
+ except: finishError = 1
+ self._request = None
+ self._response = None
+ if finishError: raise
+ finally:
+ self.spyceCleanup()
+ def spyceCleanup(self):
+ "Sweep the Spyce environment."
+ self._modstarteddefault = []
+ self._modstarted = []
+ self._modules = {}
+ if self._freshenv!=None:
+ for e in self._codeenv.keys():
+ if e not in self._freshenv:
+ del self._codeenv[e]
+ # API methods
+ def getFilename(self):
+ "Return filename of current Spyce"
+ return self._spycecode.getFilename()
+ def getCode(self):
+ "Return processed Spyce (i.e. Python) code"
+ return self._spycecode.getCode()
+ def getCodeRefs(self):
+ "Return python-to-Spyce code line references"
+ return self._spycecode.getCodeRefs()
+ def getModRefs(self):
+ "Return list of import references in Spyce code"
+ return self._spycecode.getModRefs()
+ def getServerObject(self):
+ "Return unique (per engine instance) server object"
+ return getServer().serverobject
+ def getServerGlobals(self):
+ "Return server configuration globals"
+ return getServer().globals
+ def getServerID(self):
+ "Return unique server identifier"
+ return self._request.getServerID()
+ def getPageError(self):
+ "Return default page error value"
+ return getServer().pageerror
+ def getRequest(self):
+ "Return internal request object"
+ return self._request
+ def getResponse(self):
+ "Return internal response object"
+ return self._response
+ def setResponse(self, o):
+ "Set internal response object"
+ self._response = o
+ for f in self._responseCallback.keys(): f()
+ def registerResponseCallback(self, f):
+ "Register a callback for when internal response changes"
+ self._responseCallback[f] = 1
+ def unregisterResponseCallback(self, f):
+ "Unregister a callback for when internal response changes"
+ try: del self._responseCallback[f]
+ except KeyError: pass
+ def getModules(self):
+ "Return references to currently loaded modules"
+ return self._modules
+ def getModule(self, name):
+ """Get module reference. The module is dynamically loaded and initialised
+ if it does not exist (ie. if it was not explicitly imported, but requested
+ by another module during processing)"""
+ return self._startModule(name)
+ def setModule(self, name, mod, notify=1):
+ "Add existing module (by reference) to Spyce namespace (used for includes)"
+ self._codeenv[name] = mod
+ self._modules[name] = mod
+ if notify:
+ for f in self._moduleCallback.keys():
+ f()
+ def delModule(self, name, notify=1):
+ "Add existing module (by reference) to Spyce namespace (used for includes)"
+ del self._codeenv[name]
+ del self._modules[name]
+ if notify:
+ for f in self._moduleCallback.keys():
+ f()
+ def getGlobals(self):
+ "Return the Spyce global namespace dictionary"
+ return self._codeenv
+ def registerModuleCallback(self, f):
+ "Register a callback for modules change"
+ self._moduleCallback[f] = 1
+ def unregisterModuleCallback(self, f):
+ "Unregister a callback for modules change"
+ try: del self._moduleCallback[f]
+ except KeyError: pass
+ def spyceFile(self, file):
+ "Return a spyceCode object of a file"
+ return getServer().spyce_cache[('file', file)]
+ def spyceString(self, code):
+ "Return a spyceCode object of a string"
+ return getServer().spyce_cache[('string', code)]
+ def spyceModule(self, name, file=None, rel_file=None):
+ "Return Spyce module class"
+ return getServer().loadModule(name, file, rel_file)
+ def spyceTaglib(self, name, file=None, rel_file=None):
+ "Return Spyce taglib class"
+ return getServer().loadModule(name, file, rel_file)
+ def setStdout(self, out):
+ "Set the stdout stream (thread-safe)"
+ serverout = getServer().stdout
+ if serverout: serverout.setObject(out)
+ else: sys.stdout = out
+ def getStdout(self):
+ "Get the stdout stream (thread-safe)"
+ serverout = getServer().stdout
+ if serverout: return serverout.getObject()
+ else: return sys.stdout
+
+##################################################
+# Spyce cache
+#
+
+def spyceFileCacheValid(key, validity):
+ "Determine whether compiled Spyce is valid"
+ try:
+ filename, sig = key
+ except:
+ filename, sig = key, ''
+ try:
+ if not os.path.exists(filename):
+ return 0
+ if not os.access(filename, os.R_OK):
+ return 0
+ return os.path.getmtime(filename) == validity
+ except KeyboardInterrupt: raise
+ except:
+ return 0
+
+def spyceFileCacheGenerate(key):
+ "Generate new Spyce wrapper (recompiles)."
+ try:
+ filename, sig = key
+ except:
+ filename, sig = key, ''
+ # ensure file exists and we have permissions
+ if not os.path.exists(filename):
+ raise spyceException.spyceNotFound(filename)
+ if not os.access(filename, os.R_OK):
+ raise spyceException.spyceForbidden(filename)
+ # generate
+ mtime = os.path.getmtime(filename)
+ f = None
+ try:
+ f = open(filename)
+ code = f.read()
+ finally:
+ if f: f.close()
+ s = spyceCode(code, filename=filename, sig=sig)
+ return mtime, s
+
+def spyceStringCacheValid(code, validity):
+ return 1
+
+def spyceStringCacheGenerate(key):
+ try:
+ code, sig = key
+ except:
+ code, sig = key, ''
+ s = spyceCode(code, sig=sig)
+ return None, s
+
+def spyceCacheValid((type, key), validity):
+ return {
+ 'string': spyceStringCacheValid,
+ 'file': spyceFileCacheValid,
+ }[type](key, validity)
+
+def spyceCacheGenerate((type, key)):
+ return {
+ 'string': spyceStringCacheGenerate,
+ 'file': spyceFileCacheGenerate,
+ }[type](key)
+
+
+##################################################
+# Spyce common entry points
+#
+
+def spyceFileHandler(request, response, filename, sig='', args=None, kwargs=None, config_file=None):
+ return _spyceCommonHandler(request, response, ('file', (filename, sig)), args, kwargs, config_file)
+
+def spyceStringHandler(request, response, code, sig='', args=None, kwargs=None, config_file=None):
+ return _spyceCommonHandler(request, response, ('string', (code, sig)), args, kwargs, config_file)
+
+def _spyceCommonHandler(request, response, spyceInfo, args=None, kwargs=None, config_file=None):
+ return getServer(config_file).commonHandler(request, response, spyceInfo, args, kwargs)
+
+if __name__ == '__main__':
+ execfile('run_spyceCmd.py')
+
diff --git a/system/python/spyce/spyce.spec.in b/system/python/spyce/spyce.spec.in
new file mode 100644
index 0000000000..b32a535f41
--- /dev/null
+++ b/system/python/spyce/spyce.spec.in
@@ -0,0 +1,74 @@
+%define name spyce
+%define version __VERSION__
+%define release __RELEASE__
+
+%define httpd_conf /etc/httpd/conf/httpd.conf
+%define httpd_conf_beginline ### BEGIN SPYCE CONFIG MARKER
+%define httpd_conf_endline ### END SPYCE CONFIG MARKER
+%define html_dir /var/www/html
+
+Summary: SPYCE - Python Server Pages, Python-based HTML scripting engine
+Name: %{name}
+Version: %{version}
+Release: %{release}
+Group: System/Servers
+Packager: Rimon Barr <rimon AT acm DOT org>
+URL: http://spyce.sourceforge.net
+License: Refer to LICENCE.TXT
+BuildArchitectures: noarch
+BuildRoot: %{_builddir}/%{name}-root
+#BuildRequires: python >= 2.2
+Requires: python >= 2.2
+Requires: httpd >= 2.0
+Source0: %{name}-%{version}-%{release}.tgz
+
+%description
+SPYCE is a server-side engine that supports simple and efficient Python-based
+dynamic HTML generation. Those who like Python and are familiar with JSP, or
+PHP, or ASP, should have a look at this engine. It allows one to generate
+dynamic HTML content just as easily, using Python for the dynamic parts. Its
+modular design makes it very flexible and extensible. It can also be used as a
+command-line utility for HTML pre-processing.
+
+%prep
+%setup -q
+
+%build
+make all
+
+%install
+rm -rf ${RPM_BUILD_ROOT}
+make DESTDIR=${RPM_BUILD_ROOT} install
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+/usr/share/spyce
+
+%post
+ln -sf /usr/share/spyce/run_spyceCmd.py /usr/bin/spyce
+ln -sf /usr/share/spyce/docs /usr/share/doc/spyce
+echo -n "Adding Spyce config to httpd.conf..."
+cp %httpd_conf %httpd_conf.spyce-install.bak
+sed -e "/%httpd_conf_beginline/,/%httpd_conf_endline/d" \
+ < %httpd_conf.spyce-install.bak > %httpd_conf
+echo "%httpd_conf_beginline" >> %httpd_conf
+cat /usr/share/spyce/spyceApache.conf | sed -e "s+XXX+/usr/share/spyce+g" >> %httpd_conf
+echo "%httpd_conf_endline" >> %httpd_conf
+echo " done."
+/usr/sbin/apachectl graceful
+
+%postun
+if [ $1 == 0 ]; then
+ rm -f /usr/bin/spyce
+ rm -f /usr/share/doc/spyce
+ rm -f %html_dir/spyce
+ echo -n "Removing Spyce config from httpd.conf..."
+ cp %httpd_conf %httpd_conf.spyce-uninstall.bak
+ sed -e "/%httpd_conf_beginline/,/%httpd_conf_endline/d" \
+ < %httpd_conf.spyce-uninstall.bak > %httpd_conf
+ echo " done."
+ /usr/sbin/apachectl graceful
+fi
diff --git a/system/python/spyce/spyceApache.conf b/system/python/spyce/spyceApache.conf
new file mode 100644
index 0000000000..63602f9bf2
--- /dev/null
+++ b/system/python/spyce/spyceApache.conf
@@ -0,0 +1,76 @@
+
+# XXX = Spyce program directory
+
+# This section asks your web server to serve the
+# Spyce documentation from http://localhost/spyce/.
+
+Alias /spyce/ "XXX/docs/"
+<Directory "XXX/docs">
+ Options Indexes
+ AllowOverride None
+ Order allow,deny
+ Allow from all
+</Directory>
+
+###################
+# Spyce via cgi or fcgi
+
+# This section is the default. It provides a default
+# mechanism to process .spy files. On a vanilla Apache
+# installation this will be done via CGI, which is
+# quite slow. If the FastCGI module is properly
+# installed, should automatically be used instead.
+
+AddHandler spyce-cgi-handler spy
+Action spyce-cgi-handler "/spyce-cgi/run_spyceCGI.py"
+ScriptAlias /spyce-cgi/ "XXX/"
+<Location /spyce-cgi/>
+ <IfModule mod_fastcgi.c>
+ # If mod_fastcgi not installed, we get plain cgi
+ SetHandler fastcgi-script
+ </IfModule>
+</Location>
+# If FastCGI is installed, it will be picked up
+# automatically. On Linux, you can also omit this section
+# and use a dynamic fcgi server instead.
+<IfModule mod_fastcgi.c>
+ FastCgiServer "XXX/run_spyceCGI.py" -port 7654 -initial-env FCGI_PORT=7654
+</IfModule>
+# On Windows ONLY, please uncomment the following line.
+# ScriptInterpreterSource registry
+
+###################
+# Spyce via mod_python
+
+# This section allows Spyce to be invoked via the mod_python,
+# yet another alternative with decent performance. Comment
+# the CGI/FastCGI section above entirely, and uncomment the
+# following lines, if you choose to use this instead.
+# (Note that the doubly commented lines, can remain commented
+# depending on your configuration).
+
+#<IfModule mod_python.c>
+# AddHandler python-program .spy
+# PythonHandler run_spyceModpy::spyceMain
+# PythonPath "sys.path+[r'XXX']"
+# #PythonOption SPYCE_CONFIG "/mydir/spyce.conf"
+# #PythonOptimize On
+#</IfModule>
+
+###################
+# Spyce via proxy (on port 8000)
+
+# This section direct Apache to process Spyce requests via
+# a Spyce proxy server. Comment the CGI/FastCGI section above,
+# and uncomment the following lines.
+# NB: Remember to start the Spyce proxy server...
+# spyce -l -p 8000 /document_root
+# If you would like to run your server on another port,
+# start the proxy on that port (using the -p switch)
+# and change the RewriteRule below accordingly.
+
+#<IfModule mod_rewrite.c>
+# RewriteEngine On
+# RewriteRule ^(.*\.spy) http://localhost:8000$1 [p]
+#</IfModule>
+
diff --git a/system/python/spyce/spyceCGI.py b/system/python/spyce/spyceCGI.py
new file mode 100755
index 0000000000..d7c9a26a6d
--- /dev/null
+++ b/system/python/spyce/spyceCGI.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python
+
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+import os, sys
+import spyceCmd, spyce
+import fcgi
+
+__doc__ = '''(F)CGI-based Spyce entry point.'''
+
+def findScriptFile(path):
+ origpath = path
+ while path and not path=='/':
+ if os.path.isfile(path):
+ return path
+ path = os.path.dirname(path)
+ return origpath
+
+def doSpyce( (stdin, stdout, stderr, environ) ):
+ path = None
+ if len(sys.argv)<=1 or not os.path.isfile(sys.argv[1]):
+ try: path = findScriptFile(environ['PATH_TRANSLATED'])
+ except: pass
+ result = spyceCmd.spyceMain(cgimode=1, cgiscript=path,
+ stdout=stdout, stdin=stdin, stderr=stderr, environ=environ)
+ return result
+
+def main():
+ cgi = fcgi.FCGI()
+ more = cgi.accept()
+ if cgi.socket: os.environ[spyce.SPYCE_ENTRY] = 'fcgi'
+ else: os.environ[spyce.SPYCE_ENTRY] = 'cgi'
+ while more:
+ doSpyce(more)
+ more = cgi.accept()
+
+if __name__=='__main__':
+ if sys.platform == "win32":
+ import os, msvcrt
+ msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
+ main()
+
diff --git a/system/python/spyce/spyceCache.py b/system/python/spyce/spyceCache.py
new file mode 100644
index 0000000000..ff5bd4c944
--- /dev/null
+++ b/system/python/spyce/spyceCache.py
@@ -0,0 +1,152 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+import md5, binascii, os, string
+try: from cPickle import dumps, loads
+except: from pickle import dumps, loads
+
+__doc__ = '''Caching related functionality.'''
+
+# rimtodo: specify some sort of cache size limit
+
+##################################################
+# Generic cache
+#
+
+class cache:
+ "Generic cache"
+ def __getitem__(self, key):
+ raise 'not implemented'
+ def __setitem__(self, key, value):
+ raise 'not implemented'
+ def __delitem__(self, key):
+ raise 'not implemented'
+ def keys(self):
+ raise 'not implemented'
+ def has_key(self, key):
+ raise 'not implemented'
+
+##################################################
+# Storage caches
+#
+
+class memoryCache(cache):
+ "In-memory cache"
+ def __init__(self, infoStr=None):
+ self.cache = {}
+ self.info = infoStr
+ def __getitem__(self, key):
+ return self.cache[key]
+ def __setitem__(self, key, value):
+ self.cache[key]=value
+ def __delitem__(self, key):
+ del self.cache[key]
+ def keys(self):
+ return self.cache.keys()
+ def has_key(self, key):
+ return self.cache.has_key(key)
+
+class fileCache(cache):
+ "File-based cache"
+ def __init__(self, infoStr):
+ self._cachedir = string.strip(infoStr)
+ def __getitem__(self, key):
+ filename = os.path.join(self._cachedir, self._encodeKey(key))
+ f = None
+ try:
+ try:
+ f = open(filename, 'r')
+ return loads(f.read())
+ finally:
+ if f: f.close()
+ except IOError: pass
+ except EOFError: pass
+ raise KeyError()
+ def __setitem__(self, key, value):
+ try:
+ if self[key]==value: return
+ except KeyError: pass
+ filename = os.path.join(self._cachedir, self._encodeKey(key))
+ f = None
+ try:
+ f = open(filename, 'w')
+ f.write(dumps(value,1))
+ finally:
+ if f: f.close()
+ def __delitem__(self, key):
+ filename = os.path.join(self._cachedir, self._encodeKey(key))
+ if os.path.exists(filename):
+ os.remove(filename)
+ def keys(keys):
+ raise 'not implemented'
+ def has_key(self, key):
+ try:
+ self[key]
+ return 1
+ except KeyError:
+ return 0
+ def _encodeKey(self, key):
+ return 'spyceCache-'+binascii.hexlify(md5.new(str(key)).digest())
+
+
+##################################################
+# Policy caches
+#
+
+#rimtodo:
+
+##################################################
+# Semantic cache
+#
+
+class semanticCache(cache):
+ """Cache that knows how to validate and generate its own data. Note, that the
+ cache stores elements as (validity, data) tuples. The valid is a function
+ invoked as valid(key,validity), returning a boolean; and generate is a
+ function invoked as generate(key) returning (validity, data). The get()
+ method returns only the data."""
+ def __init__(self, cache, valid, generate):
+ self.valid = valid
+ self.generate = generate
+ self.cache = cache
+ def get(self, key):
+ "Get (or generate) a cache element."
+ if self.cache:
+ if not self.cache.has_key(key) or not self.valid(key, self.cache[key][0]):
+ self.cache[key] = self.generate(key)
+ return self.cache[key][1]
+ else:
+ return self.generate(key)[1]
+ def purge(self, key):
+ "Remove a cache element, if it exists."
+ if self.cache.has_key(key):
+ del self.cache[key]
+ # standard dictionary methods
+ def __getitem__(self, key):
+ return self.get(key)
+ def __delitem__(self, key):
+ return self.purge(key)
+ def has_key(self, key):
+ if self.cache:
+ return self.cache.has_key()
+ else:
+ return 0
+ def keys(self):
+ if self.cache:
+ return self.cache.keys()
+ else:
+ return []
+ def values(self):
+ if self.cache:
+ return map(lambda x: x[1], self.cache.values())
+ else:
+ return []
+ def clear(self):
+ if self.cache:
+ self.cache.clear()
+
diff --git a/system/python/spyce/spyceCmd.py b/system/python/spyce/spyceCmd.py
new file mode 100755
index 0000000000..896354bd2e
--- /dev/null
+++ b/system/python/spyce/spyceCmd.py
@@ -0,0 +1,336 @@
+#!/usr/bin/env python
+
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+import getopt, sys, traceback, os, string, glob, copy
+import spyce, spyceException, spyceUtil
+
+__doc__ = '''Command-line and CGI-based Spyce entry point.'''
+
+##################################################
+# Output
+#
+
+# output version
+def showVersion(out=sys.stdout):
+ "Emit version information."
+ out.write('spyce v'+spyce.__version__+', by Rimon Barr: ')
+ out.write('Python Server Pages\n')
+
+# output syntax
+def showUsage(out=sys.stdout):
+ "Emit command-line usage information."
+ showVersion(out)
+ out.write('Command-line usage:\n')
+ out.write(' spyce [-c] [-o filename.html] <filename.spy>\n')
+ out.write(' spyce [-w] <filename.spy> <-- CGI\n')
+ out.write(' spyce -O filename(s).spy <-- batch process\n')
+ out.write(' spyce -l [-p port] [-d file ] [<root>] <-- proxy server\n')
+ out.write(' spyce -h | -v\n')
+ out.write(' -h, -?, --help display this help information\n')
+ out.write(' -v, --version display version\n')
+ out.write(' -o, --output send output to given file\n')
+ out.write(' -O send outputs of multiple files to *.html\n')
+ out.write(' -c, --compile compile only; do not execute\n')
+ out.write(' -w, --web cgi mode: emit headers (or use run_spyceCGI.py)\n')
+ out.write(' -q, --query set QUERY_STRING environment variable\n')
+ out.write(' -l, --listen run in HTTP server mode\n')
+ out.write(' -d, --daemon run as a daemon process with given pidfile\n')
+ out.write(' -p, --port listen on given port, default 80\n')
+ out.write(' --conf [file] Spyce configuration file\n')
+ out.write('To configure Apache, please refer to: spyceApache.conf\n')
+ out.write('For more details, refer to the documentation.\n')
+ out.write(' http://spyce.sourceforge.net\n')
+ out.write('Send comments, suggestions and bug reports to <rimon-AT-acm.org>.\n')
+
+##################################################
+# Request / Response handlers
+#
+
+class spyceCmdlineRequest(spyce.spyceRequest):
+ 'CGI/Command-line Spyce request object. (see spyce.spyceRequest)'
+ def __init__(self, input, env, filename):
+ spyce.spyceRequest.__init__(self)
+ self._in = input
+ self._env = copy.copy(env)
+ if not self._env.has_key('SERVER_SOFTWARE'):
+ self._env['SERVER_SOFTWARE'] = 'spyce %s Command-line' % spyce.__version__
+ if not self._env.has_key('REQUEST_URI'):
+ self._env['REQUEST_URI']=filename
+ if not self._env.has_key('REQUEST_METHOD'):
+ self._env['REQUEST_METHOD']='spyce'
+ if not self._env.has_key('QUERY_STRING'):
+ self._env['QUERY_STRING']=''
+ self._headers = {
+ 'Content-Length': self.env('CONTENT_LENGTH'),
+ 'Content-Type': self.env('CONTENT_TYPE'),
+ 'User-Agent': self.env('HTTP_USER_AGENT'),
+ 'Accept': self.env('HTTP_ACCEPT'),
+ 'Accept-Encoding': self.env('HTTP_ACCEPT_ENCODING'),
+ 'Accept-Language': self.env('HTTP_ACCEPT_LANGUAGE'),
+ 'Accept-Charset': self.env('HTTP_ACCEPT_CHARSET'),
+ 'Cookie': self.env('HTTP_COOKIE'),
+ 'Referer': self.env('HTTP_REFERER'),
+ 'Host': self.env('HTTP_HOST'),
+ 'Connection': self.env('HTTP_CONNECTION'),
+ 'Keep-Alive': self.env('HTTP_KEEP_ALIVE'),
+ }
+ def env(self, name=None):
+ return spyceUtil.extractValue(self._env, name)
+ def getHeader(self, type=None):
+ return spyceUtil.extractValue(self._headers, type)
+ def getServerID(self):
+ return os.getpid()
+
+class spyceCmdlineResponse(spyce.spyceResponse):
+ 'CGI/Command-line Spyce response object. (see spyce.spyceResponse)'
+ def __init__(self, out, err, cgimode=0):
+ spyce.spyceResponse.__init__(self)
+ if not cgimode:
+ self.RETURN_OK = 0
+ self.RETURN_CODE[self.RETURN_OK] = 'OK'
+ self.origout = out
+ self.out = spyceUtil.BufferedOutput(out)
+ self.err = err
+ self.cgimode = cgimode
+ self.headers = []
+ self.headersSent = 0
+ self.CT = None
+ self.returncode = self.RETURN_OK
+ # functions (for performance)
+ self.write = self.out.write
+ self.writeErr = self.err.write
+ self.clear = self.out.clear
+ def close(self):
+ self.flush()
+ self.out.close()
+ def sendHeaders(self):
+ if self.cgimode and not self.headersSent:
+ resultText = spyceUtil.extractValue(self.RETURN_CODE, self.returncode)
+ self.origout.write('Status: %3d "%s"\n' % (self.returncode, resultText))
+ if not self.CT:
+ self.setContentType('text/html')
+ self.origout.write('Content-Type: %s\n' % self.CT)
+ for h in self.headers:
+ self.origout.write('%s: %s\n'%h)
+ self.origout.write('\n')
+ self.headersSent = 1
+ def clearHeaders(self):
+ if self.headersSent:
+ raise 'headers already sent'
+ self.headers = []
+ def setContentType(self, content_type):
+ if self.headersSent:
+ raise 'headers already sent'
+ self.CT = content_type
+ def setReturnCode(self, code):
+ if self.headersSent:
+ raise 'headers already sent'
+ self.returncode = code
+ def addHeader(self, type, data, replace=0):
+ if self.headersSent:
+ raise 'headers already sent'
+ if type=='Content-Type':
+ self.setContentType(data)
+ else:
+ if replace:
+ self.headers = filter(lambda (type, _), t2=type: type!=t2, self.headers)
+ self.headers.append((type, data))
+ def flush(self, stopFlag=0):
+ if stopFlag: return
+ self.sendHeaders()
+ self.out.flush()
+ def unbuffer(self):
+ self.sendHeaders()
+ self.out.unbuffer()
+
+##################################################
+# Daemonizing
+#
+
+def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null', pidfile=None):
+ '''Forks current process into a daemon. stdin, stdout, and stderr arguments
+ are file names that are opened and used in place of the standard file descriptors
+ in sys.stdin, sys.stdout, and sys.stderr, which default to /dev/null.
+ Note that stderr is unbuffered, so output may interleave with unexpected order
+ if shares destination with stdout.'''
+ def forkToChild():
+ try:
+ if os.fork()>0: sys.exit(0) # exit parent.
+ except OSError, e:
+ sys.stderr.write("fork failed: (%d) %s\n" % (e.errno, e.strerror))
+ sys.exit(1)
+ # First fork; decouple
+ forkToChild()
+ os.chdir("/")
+ os.umask(0)
+ os.setsid()
+ # Second fork; create pidfile; redirect descriptors
+ forkToChild()
+ pid = str(os.getpid())
+ if pidfile:
+ f = open(pidfile,'w+')
+ f.write("%s\n" % pid)
+ f.close()
+ si = open(stdin, 'r')
+ so = open(stdout, 'a+')
+ se = open(stderr, 'a+', 0)
+ os.dup2(si.fileno(), sys.stdin.fileno())
+ os.dup2(so.fileno(), sys.stdout.fileno())
+ os.dup2(se.fileno(), sys.stderr.fileno())
+ # I am a daemon!
+
+##################################################
+# Command-line entry point
+#
+
+#for debugging/profiling only
+#sys.stdout = spyceUtil.NoCloseOut(sys.stdout)
+
+def spyceMain(cgimode=0, cgiscript=None,
+ stdout=sys.stdout, stdin=sys.stdin, stderr=sys.stderr, environ=os.environ):
+ "Command-line and CGI entry point."
+ # defaults
+ compileonlyMode = 0
+ outputFilename = None
+ defaultOutputFilename = 0
+ httpmode = 0
+ httpport = None
+ httproot = None
+ daemon = None
+ configFile = None
+ # parse options
+ if cgimode and cgiscript:
+ args = [cgiscript]
+ else:
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], 'h?vco:Owq:ld:p:',
+ ['help', 'version', 'compile', 'output=', 'web',
+ 'query=', 'listen', 'daemon=', 'port=', 'conf=',])
+ except getopt.error:
+ if cgimode:
+ stdout.write('Content-Type: text/plain\n\n')
+ stdout.write('syntax: unknown switch used\n')
+ stdout.write('Use -h option for help.\n')
+ return -1
+ for o, a in opts:
+ if o in ("-v", "--version"):
+ showVersion(); return
+ if o in ("-h", "--help", "-?"):
+ showUsage(); return
+ if o in ("-c", "--compileonly"):
+ compileonlyMode = 1
+ if o in ("-o", "--output"):
+ outputFilename = a
+ if o in ("-O", ):
+ defaultOutputFilename = 1
+ if o in ("-w", "--web"):
+ cgimode = 1
+ if o in ("-q", "--query"):
+ environ['QUERY_STRING'] = a
+ if o in ("-l", "--listen"):
+ httpmode = 1
+ if o in ("-d", "--daemon"):
+ daemon = a
+ if o in ("-p", "--port"):
+ try: httpport = int(a)
+ except:
+ stdout.write('syntax: port must be integer\n')
+ stdout.write('Use -h option for help.\n')
+ return -1
+ if o in ("--conf", ):
+ configFile = a
+
+ # web server mode
+ if httpmode:
+ if len(args):
+ httproot = args[0]
+ import spyceWWW
+ return spyceWWW.spyceHTTPserver(httpport, httproot, config_file=configFile, daemon=daemon)
+ # some checks
+ if not cgimode and not defaultOutputFilename and len(args)>1:
+ stdout.write('syntax: too many files to process\n')
+ stdout.write('Use -h option for help.\n')
+ return -1
+ # file globbing
+ if defaultOutputFilename:
+ globbed = map(glob.glob, args)
+ args = []
+ for g in globbed:
+ for f in g:
+ args.append(f)
+ if not len(args):
+ if cgimode:
+ stdout.write('Content-Type: text/plain\n\n')
+ stdout.write('syntax: please specify a spyce file to process\n')
+ stdout.write('Use -h option for help.\n')
+ return -1
+ # run spyce
+ result=0
+ try:
+ while len(args):
+ result=0
+ script = args[0]
+ del args[0]
+ if cgimode:
+ dir = os.path.dirname(script)
+ if dir:
+ script = os.path.basename(script)
+ os.chdir(dir)
+ try:
+ output = stdout
+ if defaultOutputFilename:
+ outputFilename = os.path.splitext(script)[0]+'.html'
+ stdout.write('Processing: %s\n'%script)
+ stdout.flush()
+ if outputFilename:
+ output = None
+ output = open(outputFilename, 'w')
+ if compileonlyMode:
+ s = spyce.getServer().spyce_cache['file', script]
+ output.write(s.getCode())
+ output.write('\n')
+ else:
+ request = spyceCmdlineRequest(stdin, environ, script)
+ response = spyceCmdlineResponse(output, stderr, cgimode)
+ result = spyce.spyceFileHandler(request, response, script)
+ response.close()
+ except KeyboardInterrupt: raise
+ except SystemExit: pass
+ except (spyceException.spyceForbidden, spyceException.spyceNotFound), e:
+ if cgimode:
+ stdout.write('Content-Type: text/plain\n\n')
+ stdout.write(str(e)+'\n')
+ except:
+ if cgimode:
+ stdout.write('Content-Type: text/plain\n\n')
+ stdout.write(spyceUtil.exceptionString()+'\n')
+ if output:
+ output.close()
+ except KeyboardInterrupt:
+ stdout.write('Break!\n')
+ return result
+
+ABSPATH = 1
+if ABSPATH:
+ for i in range(len(sys.path)):
+ sys.path[i] = os.path.abspath(sys.path[i])
+ ABSPATH = 0
+
+# Command-line entry point
+if __name__=='__main__':
+ os.environ[spyce.SPYCE_ENTRY] = 'cmd'
+ try:
+ exitcode=0
+ exitcode=spyceMain(cgimode=0)
+ except:
+ exitcode=1
+ traceback.print_exc()
+ sys.exit(exitcode)
+
diff --git a/system/python/spyce/spyceCompile.py b/system/python/spyce/spyceCompile.py
new file mode 100644
index 0000000000..b24319ae7a
--- /dev/null
+++ b/system/python/spyce/spyceCompile.py
@@ -0,0 +1,1111 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+#rimtodo:
+# - fix compaction (it assumed newlines parsed independently)
+# - active tags
+
+#try:
+# exec('import sre as re') # due to stack limitations of sre
+# # exec to be backwards compatible with Python 1.5
+#except:
+# import re
+import re # otherwise apache 2.0 pcre library conflicts
+ # we just can't win! either stack limits (sre), or
+ # library conflicts (pre)! :)
+
+from cStringIO import StringIO
+import sys, string, token, tokenize, os
+import spyceTag, spyceException, spyceUtil
+
+
+__doc__ = '''Compile Spyce files into Python code.'''
+
+##################################################
+# Special method names
+#
+
+SPYCE_CLASS = 'spyceImpl'
+SPYCE_INIT_FUNC = 'spyceStart'
+SPYCE_DESTROY_FUNC = 'spyceFinish'
+SPYCE_PROCESS_FUNC = 'spyceProcess'
+SPYCE_GLOBAL_CODE = '__SPYCE_GLOBAL_CODE_CONSTANT'
+SPYCE_WRAPPER = '_spyceWrapper'
+DEFAULT_CODEPOINT = [SPYCE_PROCESS_FUNC]
+
+##################################################
+# Dos-to-Unix linebreaks
+#
+
+# split a buffer into lines (regardless of terminators)
+def splitLines(buf):
+ lines=[]
+ f=StringIO(buf)
+ l=f.readline()
+ while len(l):
+ while l and l[-1] in ['\r', '\n']:
+ l=l[:-1]
+ lines.append(l)
+ l=f.readline()
+ return lines
+
+# encode document with LF
+def CRLF2LF(s):
+ return string.join(splitLines(s), '\n')+'\n'
+
+# encode document with CRLF
+def LF2CRLF(s):
+ return string.join(splitLines(s), '\r\n')+'\r\n'
+
+
+##################################################
+# Tokens
+#
+
+T_ESC = -2
+T_EOF = -1
+T_TEXT = 0
+T_EVAL = 1
+T_STMT = 2
+T_CHUNK = 3
+T_CHUNKG = 4
+T_DIRECT = 5
+T_LAMBDA = 6
+T_END = 7
+T_CMNT = 8
+T_END_CMNT = 9
+
+TOKENS = (
+ # in the order that they should be tested
+ # (i.e. usually longest first)
+ (T_ESC, r'\\\[\[', r'\\<%', r'\\\]\]', r'\\%>'), # escapes
+ (T_CHUNK, r'\[\[\\', r'<%\\'), # open chunk
+ (T_CHUNKG, r'\[\[\\\\', r'<%\\\\'), # open global chunk
+ (T_EVAL, r'\[\[=', r'<%='), # open eval
+ (T_DIRECT, r'\[\[\.', r'<%\.', r'<%@'), # open directive
+ (T_LAMBDA, r'\[\[spy', r'<%spy'), # open lambda
+ (T_CMNT, r'\[\[--', r'<%--'), # open comment
+ (T_END_CMNT, r'--\]\]', r'--%>'), # close comment
+ (T_STMT, r'\[\[', r'<%'), # open statement
+ (T_END, r'\]\]', r'%>'), # close
+)
+
+def genTokensRE(tokens):
+ regexp = []
+ typelookup = [None,]
+ for group in tokens:
+ type, matchstrings = group[0], group[1:]
+ for s in matchstrings:
+ regexp.append('(%s)' % s)
+ typelookup.append(type)
+ regexp = string.join(regexp, '|')
+ return re.compile(regexp, re.M), typelookup
+
+RE_TOKENS = None
+TOKEN_TYPES = None
+if not RE_TOKENS:
+ RE_TOKENS, TOKEN_TYPES = genTokensRE(TOKENS)
+
+def spyceTokenize(buf):
+ # scan using regexp
+ tokens = []
+ buflen = len(buf)
+ pos = 0
+ brow = bcol = erow = ecol = 0
+ while pos<buflen:
+ m = RE_TOKENS.search(buf, pos)
+ try:
+ mstart, mend = m.start(), m.end()
+ other, token = buf[pos:mstart], buf[mstart:mend]
+ if other:
+ tokens.append((T_TEXT, other, pos, mstart))
+ try:
+ type = TOKEN_TYPES[m.lastindex]
+ except AttributeError, e:
+ # Python 1.5 does not support lastindex
+ lastindex = 1
+ for x in m.groups():
+ if x: break
+ lastindex = lastindex + 1
+ type = TOKEN_TYPES[lastindex]
+ if type==T_ESC:
+ token = token[1:]
+ type = T_TEXT
+ tokens.append((type, token, mstart, mend))
+ pos = mend
+ except AttributeError, e:
+ # handle text before EOF...
+ other = buf[pos:]
+ if other:
+ tokens.append((T_TEXT, other, pos, buflen))
+ pos = buflen
+ # compute row, col
+ brow, bcol = 1, 0
+ tokens2 = []
+ for type, text, begin, end in tokens:
+ lines = string.split(text[:-1], '\n')
+ numlines = len(lines)
+ erow = brow + numlines - 1
+ ecol = bcol
+ if numlines>1: ecol = 0
+ ecol = ecol + len(lines[-1])
+ tokens2.append((type, text, (brow, bcol), (erow, ecol)))
+ if text[-1]=='\n':
+ brow = erow + 1
+ bcol = 0
+ else:
+ brow = erow
+ bcol = ecol + 1
+ return tokens2
+
+
+def spyceTokenize4Parse(buf):
+ # add eof and reverse (so that you can pop() tokens)
+ tokens = spyceTokenize(buf)
+ try:
+ _, _, _, end = tokens[-1]
+ except:
+ end = 0;
+ tokens.append((T_EOF, '<EOF>', end, end))
+ tokens.reverse()
+ return tokens
+
+def processMagic(buf):
+ if buf[:2]=='#!':
+ buf = string.join(string.split(buf, '\n')[1:], '\n')
+ return buf
+
+##################################################
+# Directives / Active Tags / Multi-line quotes
+#
+
+DIRECTIVE_NAME = re.compile('[a-zA-Z][-a-zA-Z0-9_:]*')
+DIRECTIVE_ATTR = re.compile(
+ r'\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\s*=\s*'
+ r'(\'[^\']*\'|"[^"]*"|[-a-zA-Z0-9./:;+*%?!&$\(\)_#=~]*))?')
+def parseDirective(text):
+ "Parse a Spyce directive into name and an attribute list."
+ attrs = {}
+ match = DIRECTIVE_NAME.match(text)
+ if not match: return None, {}
+ name = string.lower(text[:match.end()])
+ text = string.strip(text[match.end()+1:])
+ while text:
+ match = DIRECTIVE_ATTR.match(text)
+ if not match: break
+ attrname, rest, attrvalue = match.group(1, 2, 3)
+ if not rest: attrvalue = None
+ elif attrvalue[:1] == "'" == attrvalue[-1:] or \
+ attrvalue[:1] == '"' == attrvalue[-1:]:
+ attrvalue = attrvalue[1:-1]
+ attrs[string.lower(attrname)] = attrvalue
+ text = text[match.end()+1:]
+ return name, attrs
+
+RE_LIB_TAG = re.compile(r'''< # beginning of tag
+ (?P<end>/?) # ending tag
+ (?P<lib>[a-zA-Z][-.a-zA-Z0-9_]*): # lib name
+ (?P<name>[a-zA-Z][-.a-zA-Z0-9_]*) # tag name
+ (?P<attrs>(?:\s+ # attributes
+ (?:[a-zA-Z_][-.:a-zA-Z0-9_]* # attribute name
+ (?:\s*=\s* # value indicator
+ (?:'[^']*' # LITA-enclosed value
+ |"[^"]*" # LIT-enclosed value
+ |[^'">\s]+ # bare value
+ )
+ )?
+ )
+ )*)
+ \s* # trailing whitespace
+ (?P<single>/?) # single / unpaired tag
+ >''', re.VERBOSE) # end of tag
+def calcEndPos(begin, str):
+ if not str: raise 'empty string'
+ beginrow, begincol = begin
+ eol = 0
+ if str[-1]=='\n':
+ str = str[:-1]+' '
+ eol = 1
+ lines = string.split(str, '\n')
+ endrow = beginrow + len(lines)-1
+ if endrow!=beginrow:
+ begincol = 0
+ endcol = begincol + len(lines[-1]) - 1
+ beginrow, begincol = endrow, endcol + 1
+ if eol:
+ begincol = 0
+ beginrow = beginrow + 1
+ return (endrow, endcol), (beginrow, begincol)
+
+RE_MULTI_LINE_QUOTE_BEGIN = re.compile(r'r?'+"(''')|"+'(""")')
+def removeMultiLineQuotes(s):
+ def findMultiLineQuote(s):
+ quotelist = []
+ def eatToken(type, string, begin, end, _, quotelist=quotelist):
+ if type == token.STRING and RE_MULTI_LINE_QUOTE_BEGIN.match(string):
+ quotelist.append((string, begin,end))
+ tokenize.tokenize(StringIO(s).readline, eatToken)
+ return quotelist
+ def replaceRegionWithLine(s, begin, end, s2):
+ (beginrow, begincol), (endrow, endcol) = begin, end
+ beginrow, endrow = beginrow-1, endrow-1
+ s = string.split(s, '\n')
+ s1, s3 = s[:beginrow], s[endrow+1:]
+ s2 = s[beginrow][:begincol] + s2 + s[endrow][endcol:]
+ return string.join(s1 + [s2] + s3, '\n')
+ match = findMultiLineQuote(s)
+ offsets = {}
+ for _, (obr, _), (oer, _) in match:
+ offsets[obr] = oer - obr
+ while match:
+ s2, begin, end = match[0]
+ s = replaceRegionWithLine(s, begin, end, `eval(s2)`)
+ match = findMultiLineQuote(s)
+ return s, offsets
+
+##################################################
+# Pre-Python AST
+#
+
+# ast node types
+AST_PY = 0
+AST_PYEVAL = 1
+AST_TEXT = 2
+AST_COMPACT = 3
+
+# compacting modes
+COMPACT_OFF = 0
+COMPACT_LINE = 1
+COMPACT_SPACE = 2
+COMPACT_FULL = 3
+
+class ppyAST:
+ "Generate a pre-Python AST"
+ def __init__(self):
+ "Initialise parser data structures, AST, token handlers, ..."
+ # set up ast
+ self._code = {
+ 'elements': {},
+ 'leafs': [],
+ }
+ self._codepoint = self._code
+ self._codepointname = []
+ self._mods = []
+ self._taglibs = {}
+ def getCode(self):
+ return self._code
+ def getModules(self):
+ return self._mods
+ def getTaglibs(self):
+ return self._taglibs
+ # routines to navigate AST
+ def selectCodepoint(self, codepointname):
+ code = self._code
+ for point in codepointname:
+ code = code['elements'][point]
+ self._codepoint = code
+ self._codepointname = codepointname
+ def getCodepoint(self):
+ return self._codepointname
+ def descendCodepoint(self, codepointSuffix):
+ self._codepointname.append(codepointSuffix)
+ self.selectCodepoint(self._codepointname)
+ def ascendCodepoint(self):
+ suffix = self._codepointname.pop()
+ self.selectCodepoint(self._codepointname)
+ return suffix
+ # routines that modify the ast
+ def appendCodepoint(self, codepointSuffix, firstline, ref=None):
+ self._codepoint['elements'][codepointSuffix] = {
+ 'elements': {},
+ 'leafs': [],
+ }
+ self.descendCodepoint(codepointSuffix)
+ self.addCode(string.strip(firstline), ref) # note: firstline is not indented
+ def addCode(self, code, ref=None):
+ self._codepoint['leafs'].append((AST_PY, code, ref))
+ def addGlobalCode(self, code, ref=None):
+ codepoint = self.getCodepoint()
+ self.selectCodepoint([SPYCE_GLOBAL_CODE])
+ self.addCode(code+'\n', ref)
+ self.selectCodepoint(codepoint)
+ pass
+ def addEval(self, eval, ref=None):
+ self._codepoint['leafs'].append((AST_PYEVAL, eval, ref))
+ def addCodeIndented(self, code, ref=None, globalcode=0):
+ code, replacelist = removeMultiLineQuotes(code)
+ # funky hack: put in NULLs to preserve indentation
+ # NULLs don't appear in code, and the BraceConverter will
+ # turn them back into spaces. If we leave them as spaces,
+ # BraceConverter is just going to ignore them and pay attention
+ # only to the braces. (not the best compile-time performance!)
+ code = string.split(code, '\n')
+ code = map(lambda l: (len(l)-len(string.lstrip(l)), l), code)
+ code = map(lambda (indent, l): chr(0)*indent + l, code)
+ code.append('')
+ # split code lines
+ (brow, bcol), (erow, ecol), text, file = ref
+ row = brow
+ for l in code:
+ cbcol = 0
+ cecol = len(l)
+ if row==brow: cbcol = bcol
+ if row==erow: cecol = ecol
+ try: row2 = row + replacelist[row-brow+1]
+ except: row2 = row
+ ref = (row, cbcol), (row2, cecol), l, file
+ if globalcode: self.addGlobalCode(l, ref)
+ else: self.addCode(l, ref)
+ row = row2 + 1
+ def addText(self, text, ref=None):
+ self._codepoint['leafs'].append((AST_TEXT, text, ref))
+ def addCompact(self, compact, ref):
+ self._codepoint['leafs'].append((AST_COMPACT, compact, ref))
+ def addModule(self, modname, modfrom, modas):
+ self._mods.append((modname, modfrom, modas))
+ def addTaglib(self, libname, libfrom=None, libas=None):
+ if not libas: libas=libname
+ self._taglibs[libas] = libname, libfrom
+
+
+##################################################
+# Parse
+#
+
+class spyceParse:
+ def __init__(self, server, buf, filename, sig):
+ try:
+ # initialization
+ self._tagChecker = spyceTag.spyceTagChecker(server)
+ self._load_spylambda = 0
+ self._load_taglib = 0
+ self._curdir, self._curfile = os.getcwd(), '<string>'
+ if filename:
+ self._curdir, self._curfile = os.path.split(filename)
+ if not self._curdir:
+ self._curdir = os.getcwd()
+ # prime ast
+ self._ast = ppyAST()
+ self._ast.selectCodepoint([])
+ self._ast.appendCodepoint(SPYCE_GLOBAL_CODE, '')
+ self._ast.addGlobalCode('''
+try:
+ exec('from __future__ import nested_scopes')
+except: pass
+from spyceException import spyceDone, spyceRedirect, spyceRuntimeException
+ ''')
+ # define spyceProcess
+ self._ast.selectCodepoint([])
+ self._ast.appendCodepoint(SPYCE_PROCESS_FUNC, 'def '+SPYCE_PROCESS_FUNC+'('+sig+')')
+ # spyceProcess pre
+ self._ast.selectCodepoint(DEFAULT_CODEPOINT)
+ self._ast.addCode('try:{', None)
+ self._ast.addCode('pass', None)
+ # spyceProcess body
+ self._tokens = spyceTokenize4Parse(processMagic(buf))
+ self._tokenType = None
+ self.popToken()
+ self.processSpyce()
+ # spyceProcess post
+ self._ast.addCode('} except spyceDone: pass', None)
+ self._ast.addCode('except spyceRedirect: raise', None)
+ self._ast.addCode('except KeyboardInterrupt: raise', None)
+ self._ast.addCode('except:{ raise spyceRuntimeException(%s) }'%SPYCE_WRAPPER, None)
+ # post processing
+ if self._load_taglib: self._ast.addModule('taglib', None, None)
+ if self._load_spylambda: self._ast.addModule('spylambda', None, None)
+ self._tagChecker.finish()
+ except spyceException.spyceSyntaxError, e:
+ raise
+ if e.info:
+ begin, end, text, _ = e.info
+ e.info = begin, end, text, self._curfile
+ raise e
+ def info(self):
+ return self._ast.getCode(), self._ast.getModules()
+ def popToken(self):
+ if self._tokenType!=T_EOF:
+ self._tokenType, self._tokenText, self._tokenBegin, self._tokenEnd = self._tokens.pop()
+
+ def processSpyce(self):
+ while self._tokenType!=T_EOF:
+ [
+ self.processText, # T_TEXT
+ self.processEval, # T_EVAL
+ self.processStmt, # T_STMT
+ self.processChunk, # T_CHUNK
+ self.processGlobalChunk, # T_CHUNKG
+ self.processDirective, # T_DIRECT
+ self.processUnexpected, # T_LAMBDA
+ self.processUnexpected, # T_END
+ self.processComment, # T_CMNT
+ self.processUnexpected, # T_END_CMNT
+ ][self._tokenType]()
+ self.popToken()
+ def processComment(self):
+ # collect comment
+ self.popToken()
+ while self._tokenType not in [T_END_CMNT, T_EOF]:
+ self.popToken()
+ if self._tokenType==T_EOF:
+ self.processUnexpected()
+ def processText(self):
+ "Process HTML (possibly with some active tags)"
+ html, begin, end = self._tokenText, self._tokenBegin, self._tokenEnd
+ m = RE_LIB_TAG.search(html)
+ while m:
+ plain = html[:m.start()]
+ if plain:
+ plain_end, tag_begin = calcEndPos(begin, plain)
+ self._ast.addText(plain, (begin, plain_end, '<html string>', self._curfile))
+ else: tag_begin = begin
+ tag = m.group(0)
+ tag_end, begin = calcEndPos(tag_begin, tag)
+ self.processActiveTag(tag,
+ not not m.group('end'), m.group('lib'), m.group('name'),
+ m.group('attrs'), not m.group('single'),
+ tag_begin, tag_end)
+ html = html[m.end():]
+ m = RE_LIB_TAG.search(html)
+ self._ast.addText(html, (begin, end, '<html string>', self._curfile))
+ def processActiveTag(self, tag, tagend, taglib, tagname, tagattrs, tagpair, begin, end):
+ "Process HTML tags"
+ # make sure prefix belongs to loaded taglibrary
+ if not self._ast._taglibs.has_key(taglib):
+ self._ast.addText(tag, (begin, end, '<html string>', self._curfile))
+ return
+ # parse process tag attributes
+ _, tagattrs = parseDirective('x '+tagattrs)
+ # get tag class
+ tagclass = self._tagChecker.getTagClass(self._ast._taglibs[taglib],
+ tagname, (begin, end, tag, self._curfile))
+ # syntax check
+ if not tagend: # start tag
+ self._tagChecker.startTag(self._ast._taglibs[taglib],
+ tagname, tagattrs, tagpair, (begin, end, tag, self._curfile))
+ else: # end tag
+ self._tagChecker.endTag(self._ast._taglibs[taglib],
+ tagname, (begin, end, tag, self._curfile))
+ # add python code for active tag
+ if not tagend or not tagpair: # open or singleton tag
+ self._ast.addCode('try: { taglib.tagPush(%s, %s, %s, %s)' % (
+ repr(taglib), repr(tagname), repr(tagattrs), repr(tagpair)),
+ (begin, end, tag, self._curfile))
+ if tagclass.catches:
+ self._ast.addCode('try: {', (begin, end, tag, self._curfile))
+ if tagclass.conditional:
+ self._ast.addCode('if taglib.tagBegin(): {', (begin, end, tag, self._curfile))
+ else:
+ self._ast.addCode('taglib.tagBegin()', (begin, end, tag, self._curfile))
+ if tagclass.mustend:
+ self._ast.addCode('try: {', (begin, end, tag, self._curfile))
+ if tagclass.loops:
+ self._ast.addCode('while 1: {', (begin, end, tag, self._curfile))
+ if tagend or not tagpair: # close or singleton tag
+ if tagclass.loops:
+ self._ast.addCode('if not taglib.tagBody(): break }', (begin, end, tag, self._curfile))
+ else:
+ self._ast.addCode('taglib.tagBody()', (begin, end, tag, self._curfile))
+ if tagclass.mustend:
+ self._ast.addCode('} finally: taglib.tagEnd()', (begin, end, tag, self._curfile))
+ else:
+ self._ast.addCode('taglib.tagEnd()', (begin, end, tag, self._curfile))
+ if tagclass.conditional:
+ self._ast.addCode('}', (begin, end, tag, self._curfile))
+ if tagclass.catches:
+ self._ast.addCode('} except: taglib.tagCatch()', (begin, end, tag, self._curfile))
+ self._ast.addCode('} finally: taglib.tagPop()', (begin, end, tag, self._curfile))
+ def processEval(self):
+ # collect expression
+ begin = self._tokenBegin
+ self.popToken()
+ expr = ''
+ while self._tokenType not in [T_END, T_EOF]:
+ if self._tokenType==T_TEXT:
+ expr = expr + self._tokenText
+ elif self._tokenType==T_LAMBDA:
+ expr = expr + self.processLambda()
+ else: self.processUnexpected()
+ self.popToken()
+ expr = string.strip(expr)
+ if not expr: self.processUnexpected()
+ # add expression to ast
+ self._ast.addEval(expr, (begin, self._tokenEnd, '='+expr, self._curfile))
+ def processStmt(self):
+ # collect statement
+ self.popToken()
+ beginrow, begincol = self._tokenBegin
+ stmt = ''
+ while self._tokenType not in [T_END, T_EOF]:
+ if self._tokenType==T_TEXT:
+ stmt = stmt + self._tokenText
+ elif self._tokenType==T_LAMBDA:
+ stmt = stmt + self.processLambda()
+ else: self.processUnexpected()
+ endrow, endcol = self._tokenEnd
+ self.popToken()
+ if not string.strip(stmt): self.processUnexpected()
+ # add statement to ast, row-by-row
+ currow = beginrow
+ lines = string.split(stmt, '\n')
+ for l in lines:
+ if currow==beginrow: curcolbegin = begincol
+ else: curcolbegin = 0
+ if currow==endrow: curcolend = endcol
+ else: curcolend = len(l)
+ l = string.strip(l)
+ if l:
+ self._ast.addCode(l, ((currow, curcolbegin), (currow, curcolend), l, self._curfile))
+ currow = currow + 1
+ def processChunk(self, globalChunk=0):
+ # collect chunk
+ self.popToken()
+ begin = self._tokenBegin
+ chunk = ''
+ while self._tokenType not in [T_END, T_EOF]:
+ if self._tokenType==T_TEXT:
+ chunk = chunk + self._tokenText
+ elif self._tokenType==T_LAMBDA:
+ chunk = chunk + self.processLambda()
+ else: self.processUnexpected()
+ end = self._tokenEnd
+ self.popToken()
+ chunk = string.split(chunk, '\n')
+ # eliminate initial blank lines
+ brow, bcol = begin
+ while chunk and not string.strip(chunk[0]):
+ chunk = chunk[1:]
+ brow = brow + 1
+ bcol = 0
+ begin = brow, bcol
+ if not chunk: self.processUnexpected()
+ # outdent chunk based on first line
+ # note: modifies multi-line strings having more spaces than first line outdent
+ # by removing outdent number of spaces at the beginning of each line.
+ # -- difficult to deal with efficiently (without parsing python) so just
+ # don't do this!
+ outdent = len(chunk[0]) - len(string.lstrip(chunk[0]))
+ for i in range(len(chunk)):
+ if string.strip(chunk[i][:outdent]):
+ chunk[i] = ' '*outdent + chunk[i]
+ chunk = map(lambda l, outdent=outdent: l[outdent:], chunk)
+ chunk = string.join(chunk, '\n')
+ # add chunk block at ast
+ if chunk:
+ try:
+ self._ast.addCodeIndented(chunk, (begin, end, chunk, self._curfile), globalChunk)
+ except tokenize.TokenError, e:
+ msg, _ = e
+ raise spyceException.spyceSyntaxError(msg, (begin, end, chunk, self._curfile) )
+ def processGlobalChunk(self):
+ self.processChunk(1)
+ def processDirective(self):
+ # collect directive
+ begin = self._tokenBegin
+ self.popToken()
+ directive = ''
+ while self._tokenType not in [T_END, T_EOF]:
+ if self._tokenType==T_TEXT:
+ directive = directive + self._tokenText
+ else: self.processUnexpected()
+ end = self._tokenEnd
+ self.popToken()
+ directive = string.strip(directive)
+ if not directive: self.processUnexpected()
+ # process directives
+ name, attrs = parseDirective(directive)
+ if name=='compact':
+ compact_mode = COMPACT_FULL
+ if attrs.has_key('mode'):
+ mode = string.lower(attrs['mode'])
+ if mode=='off':
+ compact_mode = COMPACT_OFF
+ elif mode=='line':
+ compact_mode = COMPACT_LINE
+ elif mode=='space':
+ compact_mode = COMPACT_SPACE
+ elif mode=='full':
+ compact_mode = COMPACT_FULL
+ else:
+ raise spyceException.spyceSyntaxError('invalid compacting mode "%s" specified'%mode, (begin, end, directive, self._curfile))
+ self._ast.addCompact(compact_mode, (begin, end, '<spyce compact directive>', self._curfile))
+ elif name in ('module', 'import'):
+ if not attrs.has_key('name') and not attrs.has_key('names'):
+ raise spyceException.spyceSyntaxError('name or names attribute required', (begin, end, directive, self._curfile) )
+ if attrs.has_key('names'):
+ mod_names = filter(None, map(string.strip, string.split(attrs['names'],',')))
+ for mod_name in mod_names:
+ self._ast.addModule(mod_name, None, None)
+ self._ast.addCode('%s.init()'%mod_name, (begin, end, directive, self._curfile))
+ else:
+ mod_name = attrs['name']
+ mod_from = spyceUtil.extractValue(attrs, 'from')
+ mod_as = spyceUtil.extractValue(attrs, 'as')
+ mod_args = spyceUtil.extractValue(attrs, 'args', '')
+ if mod_as: theName=mod_as
+ else: theName=mod_name
+ self._ast.addModule(mod_name, mod_from, mod_as)
+ self._ast.addCode('%s.init(%s)'%(theName,mod_args), (begin, end, directive, self._curfile))
+ elif name in ('taglib',):
+ if not attrs.has_key('name') and not attrs.has_key('names'):
+ raise spyceException.spyceSyntaxError('name or names attribute required', (begin, end, directive, self._curfile) )
+ fullfile = os.path.join(self._curdir, self._curfile)
+ if attrs.has_key('names'):
+ taglib_names = filter(None, map(string.strip, string.split(attrs['names'],',')))
+ for taglib_name in taglib_names:
+ self._tagChecker.loadLib(taglib_name, None, None, fullfile, (begin, end, directive, self._curfile))
+ self._ast.addTaglib(taglib_name)
+ self._load_taglib = 1
+ self._ast.addCode('taglib.load(%s)'%repr(taglib_name), (begin, end, directive, self._curfile))
+ else:
+ taglib_name = attrs['name']
+ taglib_from = spyceUtil.extractValue(attrs, 'from')
+ taglib_as = spyceUtil.extractValue(attrs, 'as')
+ self._tagChecker.loadLib(taglib_name, taglib_from, taglib_as, fullfile, (begin, end, directive, self._curfile))
+ self._ast.addTaglib(taglib_name, taglib_from, taglib_as)
+ self._load_taglib = 1
+ self._ast.addCode('taglib.load(%s, %s, %s)'%(repr(taglib_name), repr(taglib_from), repr(taglib_as)), (begin, end, directive, self._curfile))
+ elif name=='include':
+ if not attrs.has_key('file'):
+ raise spyceException.spyceSyntaxError('file attribute missing', (begin, end, directive, self._curfile) )
+ filename = os.path.join(self._curdir, attrs['file'])
+ f = None
+ try:
+ try:
+ f = open(filename)
+ buf = f.read()
+ finally:
+ if f: f.close()
+ except KeyboardInterrupt: raise
+ except:
+ raise spyceException.spyceSyntaxError('unable to open included file: %s'%filename, (begin, end, directive, self._curfile) )
+ prev = (self._curdir, self._curfile, self._tokens,
+ self._tokenType, self._tokenText, self._tokenBegin, self._tokenEnd)
+ self._curdir, self._curfile = os.path.dirname(filename), filename
+ self._tokens = spyceTokenize4Parse(processMagic(buf))
+ self.popToken()
+ self.processSpyce()
+ (self._curdir, self._curfile, self._tokens,
+ self._tokenType, self._tokenText, self._tokenBegin, self._tokenEnd) = prev
+ else:
+ raise spyceException.spyceSyntaxError('invalid spyce directive', (begin, end, directive, self._curfile) )
+ def processLambda(self):
+ # collect lambda
+ self.popToken()
+ begin = self._tokenBegin
+ lamb = ''
+ depth = 1
+ while self._tokenType!=T_EOF:
+ if self._tokenType in [T_END,]:
+ depth = depth - 1
+ if not depth: break
+ lamb = lamb + self._tokenText
+ elif self._tokenType in [T_EVAL, T_STMT, T_CHUNK, T_CHUNKG, T_DIRECT, T_LAMBDA]:
+ depth = depth + 1
+ lamb = lamb + self._tokenText
+ elif self._tokenType==T_CMNT:
+ self.processComment()
+ else:
+ lamb = lamb + self._tokenText
+ end = self._tokenEnd
+ self.popToken()
+ # process lambda
+ lamb = string.split(lamb, ':')
+ try:
+ params = lamb[0]
+ memoize = 0
+ if params and params[0]=='!':
+ params = params[1:]
+ memoize = 1
+ lamb = string.join(lamb[1:],':')
+ except:
+ raise spyceException.spyceSyntaxError('invalid spyce lambda', (begin, end, lamb, self._curfile))
+ self._load_spylambda = 1
+ lamb = 'spylambda.define(%s,%s,%d)' % (`string.strip(params)`, `lamb`, memoize)
+ return lamb
+ def processUnexpected(self):
+ raise spyceException.spyceSyntaxError('unexpected token: "%s"'%self._tokenText,
+ (self._tokenBegin, self._tokenEnd, self._tokenText, self._curfile))
+
+##################################################
+# Peep-hole optimizer
+#
+
+class spyceOptimize:
+ def __init__(self, ast):
+ self.compaction(ast)
+ self.sideBySideWrites(ast)
+ #self.splitCodeLines(ast)
+ def splitCodeLines(self, ast):
+ elements, leafs = ast['elements'], ast['leafs']
+ for el in elements.keys():
+ self.splitCodeLines(elements[el])
+ if leafs:
+ i = 0
+ while i<len(leafs):
+ row = 1
+ type, text, ref = leafs[i]
+ if type == AST_PY and ref:
+ (brow, bcol), (erow, ecol), code, file = ref
+ lines = string.split(code, '\n')
+ if code==text and len(lines)>1:
+ del leafs[i]
+ row = brow
+ for l in lines:
+ cbcol = 0
+ cecol = len(l)
+ if row==brow: cbcol = bcol
+ if row==erow: becol = ecol
+ leafs.insert(i+(brow-row), (AST_PY, l, ((row, cbcol), (row, cecol), l, file)))
+ row = row + 1
+ i = i + row
+
+ def sideBySideWrites(self, ast):
+ elements, leafs = ast['elements'], ast['leafs']
+ for el in elements.keys():
+ self.sideBySideWrites(elements[el])
+ if leafs:
+ i = 0
+ while i+1<len(leafs):
+ type1, text1, ref1 = leafs[i]
+ type2, text2, ref2 = leafs[i+1]
+ file1 = None
+ file2 = None
+ if ref1:
+ _, _, _, file1 = ref1
+ if ref2:
+ _, _, _, file2 = ref2
+ if type1==AST_TEXT and type2==AST_TEXT and file1==file2:
+ text = text1 + text2
+ begin, _, orig, _ = ref1
+ _, end, _, _ = ref2
+ leafs[i] = AST_TEXT, text, (begin, end, orig, file1)
+ del leafs[i+1]
+ i = i - 1
+ i = i+1
+ def compaction(self, ast):
+ elements, leafs = ast['elements'], ast['leafs']
+ compact = COMPACT_LINE
+ for el in elements.keys():
+ self.compaction(elements[el])
+ if leafs:
+ i = 0
+ while i<len(leafs):
+ type, text, ref = leafs[i]
+ if type==AST_COMPACT:
+ compact = text
+ elif type==AST_TEXT:
+ # line compaction
+ if compact==COMPACT_LINE or compact==COMPACT_FULL:
+ # remove any trailing whitespace
+ text = string.split(text, '\n')
+ for j in range(len(text)-1):
+ text[j] = string.rstrip(text[j])
+ text = string.join(text, '\n')
+ # gobble the end of the line
+ ((row, _), _, _, file) = ref
+ rowtext = string.split(text, '\n')
+ if rowtext: rowtext = string.strip(rowtext[0])
+ crow = row ; cfile = file
+ j = i
+ while j and not rowtext:
+ j = j - 1
+ type2, text2, ref2 = leafs[j]
+ if ref2: (_, (crow, _), _, cfile) = ref2
+ if crow != row or file != cfile: break
+ if type2 == AST_TEXT:
+ text2 = string.split(text2, '\n')
+ if text2: text2 = text2[-1]
+ rowtext = rowtext + string.strip(text2)
+ elif type2 == AST_PYEVAL:
+ rowtext = 'x'
+ if not rowtext:
+ text = string.split(text, '\n')
+ if text and not string.strip(text[0]):
+ text = text[1:]
+ text = string.join(text, '\n')
+ # gobble beginning of the line
+ (_, (row, _), _, file) = ref
+ rowtext = string.split(text, '\n')
+ if rowtext: rowtext = string.strip(rowtext[-1])
+ crow = row ; cfile = file
+ j = i + 1
+ while j<len(leafs) and not rowtext:
+ type2, text2, ref2 = leafs[j]
+ if ref2: ((crow, _), _, _, cfile) = ref2
+ if crow != row or file != cfile: break
+ if type2 == AST_TEXT:
+ text2 = string.split(text2, '\n')
+ if text2: text2 = text2[0]
+ rowtext = rowtext + string.strip(text2)
+ elif type2 == AST_PYEVAL:
+ rowtext = 'x'
+ j = j + 1
+ if not rowtext:
+ text = string.split(text, '\n')
+ if text: text[-1] = string.strip(text[-1])
+ text = string.join(text, '\n')
+ # space compaction
+ if compact==COMPACT_SPACE or compact==COMPACT_FULL:
+ text = spyceUtil.spaceCompact(text)
+ # update text, if any
+ if text: leafs[i] = type, text, ref
+ else:
+ del leafs[i]
+ i = i -1
+ elif type in [AST_PY, AST_PYEVAL]:
+ pass
+ else:
+ raise 'error: unknown AST node type'
+ i = i + 1
+
+##################################################
+# Output classes
+#
+
+class LineWriter:
+ "Output class that counts lines written."
+ def __init__(self, f, initialLine = 1):
+ self.f = f
+ self.lineno = initialLine
+ def write(self, s):
+ self.f.write(s)
+ self.lineno = self.lineno + len(string.split(s,'\n'))-1
+ def writeln(self, s):
+ self.f.write(s+'\n')
+ def close(self):
+ self.f.close()
+
+class IndentingWriter:
+ "Output class that helps with indentation of code."
+ # Note: this writer is line-oriented.
+ def __init__(self, f, indentSize=2):
+ self._f = f
+ self._indentSize = indentSize
+ self._indent = 0
+ self._indentString = ' '*(self._indent*self._indentSize)
+ self._currentLine = ''
+ def close(self):
+ if self._indent > 0:
+ raise 'unmatched open brace'
+ self._f.close()
+ def indent(self):
+ self._indent = self._indent + 1
+ self._indentString = ' '*(self._indent*self._indentSize)
+ def outdent(self):
+ self._indent = self._indent - 1
+ if self._indent<0:
+ raise 'unmatched close brace'
+ self._indentString = ' '*(self._indent*self._indentSize)
+ def dumpLine(self, s):
+ self._f.write(self._indentString+s+'\n')
+ def write(self, s):
+ self._currentLine = self._currentLine + s
+ lines = string.split(self._currentLine, '\n')
+ for l in lines[:-1]:
+ self.dumpLine(l)
+ self._currentLine=lines[-1]
+ def writeln(self, s=''):
+ self.write(s+'\n')
+ # remaining methods are defined in terms of writeln(), indent(), outdent()
+ def pln(self, s=''):
+ self.writeln(s)
+ def pIln(self, s=''):
+ self.indent(); self.pln(s)
+ def plnI(self, s=''):
+ self.pln(s); self.indent()
+ def pOln(self, s=''):
+ self.outdent(); self.pln(s)
+ def plnO(self, s=''):
+ self.pln(s); self.outdent()
+ def pOlnI(self, s=''):
+ self.outdent(); self.pln(s); self.indent()
+ def pIlnO(self, s=''):
+ self.indent(); self.pln(s); self.outdent()
+
+##################################################
+# Print out Braced Python
+#
+
+class emitBracedPython:
+ def __init__(self, out, ast):
+ out = LineWriter(out)
+ self._spyceRefs = {}
+ # text compaction
+ self.compact = COMPACT_LINE
+ self._gobblelineNumber = 1
+ self._gobblelineText = ''
+ # do the deed!
+ self.emitSpyceRec(out, self._spyceRefs, None, ast['elements'], ast['leafs'][1:])
+ def getSpyceRefs(self):
+ return self._spyceRefs
+ def emitSpyceRec(self, out, spyceRefs, header, elements, leafs):
+ if header:
+ out.write(header+':{\n')
+ def processLevel(el, out=out, spyceRefs=spyceRefs, self=self):
+ self.emitSpyceRec(out, spyceRefs, el['leafs'][0][1], el['elements'], el['leafs'][1:])
+ try:
+ processLevel(elements[SPYCE_GLOBAL_CODE])
+ del elements[SPYCE_GLOBAL_CODE]
+ except KeyError: pass
+ for el in elements.keys():
+ processLevel(elements[el])
+ if leafs:
+ for type, text, ref in leafs:
+ line1 = out.lineno
+ if type==AST_TEXT:
+ out.write('response.writeStatic(%s)\n' % `text`)
+ elif type==AST_PY:
+ out.write(text+'\n')
+ elif type==AST_PYEVAL:
+ out.write('response.writeExpr(%s)\n' % text)
+ elif type==AST_COMPACT:
+ self.compact = text
+ else:
+ raise 'error: unknown AST node type'
+ line2 = out.lineno
+ if ref:
+ for l in range(line1, line2):
+ spyceRefs[l] = ref
+ if not leafs and not elements:
+ out.write('pass\n')
+ if header:
+ out.write('}\n')
+
+##################################################
+# Print out regular Python
+#
+
+class BraceConverter:
+ "Convert Python with braces into indented (normal) Python code."
+ def __init__(self, out):
+ self.out = IndentingWriter(out)
+ self.prevname = 0
+ self.prevstring = 0
+ self.dictlevel = 0
+ def emitToken(self, type, string):
+ if type==token.NAME:
+ if self.prevname: self.out.write(' ')
+ if self.prevstring: self.out.write(' ')
+ self.out.write(string)
+ elif type==token.STRING:
+ if self.prevname: self.out.write(' ')
+ string = `eval(string)` # get rid of multi-line strings
+ self.out.write(string)
+ elif type==token.NUMBER:
+ if self.prevname: self.out.write(' ')
+ self.out.write(string)
+ elif type==token.OP:
+ if string=='{':
+ if self.prevcolon and not self.dictlevel:
+ self.out.plnI()
+ else:
+ self.dictlevel = self.dictlevel + 1
+ self.out.write(string)
+ elif string=='}':
+ if not self.dictlevel:
+ self.out.plnO()
+ else:
+ self.dictlevel = self.dictlevel - 1
+ self.out.write(string)
+ else:
+ self.out.write(string)
+ elif type==token.ERRORTOKEN and string==chr(0):
+ self.out.write(' ')
+ else:
+ #print type, token.tok_name[type], `string`
+ self.out.write(string)
+ self.prevname = type==token.NAME
+ self.prevstring = type==token.STRING
+ self.prevcolon = type==token.OP and string==':'
+
+def emitPython(out, bracedPythonCode, spyceRefs):
+ out = LineWriter(out)
+ spyceRefs2 = {}
+ braceConv = BraceConverter(out)
+ def eatToken(type, string, begin, end, _, out=out, braceConv=braceConv, spyceRefs=spyceRefs, spyceRefs2=spyceRefs2):
+ try:
+ beginrow, _ = begin
+ line1 = out.lineno
+ braceConv.emitToken(type, string)
+ line2 = out.lineno
+ if spyceRefs.has_key(beginrow):
+ for l in range(line1, line2):
+ spyceRefs2[l] = spyceRefs[beginrow]
+ except:
+ raise spyceException.spyceSyntaxError(sys.exc_info()[0])
+ try:
+ tokenize.tokenize(StringIO(bracedPythonCode).readline, eatToken)
+ except tokenize.TokenError, e:
+ msg, (row, col) = e
+ raise spyceException.spyceSyntaxError(msg)
+ return spyceRefs2
+
+def calcRowCol(str, pos):
+ lines = string.split(str, '\n')
+ row = 1
+ while pos > len(lines[0]):
+ pos = pos - len(lines[0]) - 1
+ del lines[0]
+ row = row + 1
+ return row, pos
+
+RE_BRACES = re.compile('{|}')
+def checkBalancedParens(str, refs):
+ m = RE_BRACES.search(str)
+ stack = []
+ try:
+ while m:
+ if m.group(0)=='{': stack.append(m)
+ else: stack.pop()
+ m = RE_BRACES.search(str, m.end())
+ except IndexError:
+ row, _ = calcRowCol(str, m.start())
+ try: info = refs[row]
+ except KeyError: info =None
+ raise spyceException.spyceSyntaxError("unbalanced open brace '{'", info)
+ if stack:
+ m = stack[-1]
+ row, _ = calcRowCol(str, m.start())
+ try: info = refs[row]
+ except KeyError: info =None
+ raise spyceException.spyceSyntaxError("unbalanced close brace '}'", info)
+
+##############################################
+# Compile spyce files
+#
+
+def spyceCompile(buf, filename, sig, server):
+ # parse
+ ast, libs = spyceParse(server, CRLF2LF(buf), filename, sig).info()
+ # optimize the ast
+ spyceOptimize(ast)
+ # generate braced code
+ out = StringIO()
+ refs = emitBracedPython(out, ast).getSpyceRefs()
+ # then, generate regular python code
+ bracedPythonCode = out.getvalue()
+ checkBalancedParens(bracedPythonCode, refs)
+ out = StringIO()
+ refs = emitPython(out, bracedPythonCode, refs)
+ return out.getvalue(), refs, libs
+
+def test():
+ import spyce
+ f = open(sys.argv[1])
+ spycecode = f.read()
+ f.close()
+ tokens = spyceTokenize(processMagic(CRLF2LF(spycecode)))
+ for type, text, begin, end in tokens:
+ print '%s (%s, %s): %s' % (type, begin, end, `text`)
+ pythoncode, refs, libs = spyceCompile(spycecode, sys.argv[1], '', spyce.getServer())
+ print pythoncode
+
+if __name__ == '__main__':
+ test()
+
diff --git a/system/python/spyce/spyceConfig.py b/system/python/spyce/spyceConfig.py
new file mode 100644
index 0000000000..85c0c99359
--- /dev/null
+++ b/system/python/spyce/spyceConfig.py
@@ -0,0 +1,370 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+import sys, os, string, ConfigParser
+import spyceException
+
+##################################################
+# Constants
+#
+
+SPYCE_CONCURRENCY_SINGLE = 0
+SPYCE_CONCURRENCY_FORK = 1
+SPYCE_CONCURRENCY_THREAD = 2
+
+SPYCE_CONFIG_LOCATIONS = [
+ '/etc',
+]
+SPYCE_CONFIG_FILENAME = 'spyce.conf'
+SPYCE_HOME = None
+
+##################################################
+# determine HOME (installation) directory
+#
+
+if SPYCE_HOME == None:
+ try:
+ SPYCE_HOME = os.path.abspath(os.path.dirname(sys.modules['spyceConfig'].__file__))
+ except:
+ for p in sys.path:
+ path = os.path.join(p, 'spyceConfig.py')
+ if os.path.exists(path):
+ SPYCE_HOME = os.path.abspath(p)
+ break
+ if not SPYCE_HOME:
+ raise 'unable to determine Spyce home directory'
+
+##################################################
+# Server configuration object
+#
+
+class spyceConfig:
+ def __init__(self,
+ file=None,
+ overide_path=None,
+ overide_import=None,
+ overide_error=None,
+ overide_pageerror=None,
+ overide_globals=None,
+ overide_debug=None,
+ default_concurrency=None, # no concurrency
+ overide_concurrency=None,
+ overide_cache=None,
+ default_www_root='.', # serve from current directory
+ overide_www_root=None,
+ default_www_port=80, # default HTTP
+ overide_www_port=None,
+ default_www_handler={
+ 'spy': 'spyce',
+ None: 'dump',
+ },
+ default_www_mime = [os.path.join(SPYCE_HOME,'spyce.mime')],
+ ):
+ self.file = file
+ self._procesed = 0
+ # config parameters
+ self.spyce_config = None # spyce configuration dictionary
+ self.spyce_path = None # spyce module search path
+ self.spyce_import = None # python modules loaded at startup
+ self.spyce_error = None # spyce engine-level error handler
+ self.spyce_pageerror = None # spyce page-level error handler
+ self.spyce_globals = {} # spyce engine globals dictionary
+ self.spyce_debug = None # spyce engine debug flag
+ self.spyce_concurrency = None # concurrency model
+ self.spyce_www_root = None # root directory for spyce web server
+ self.spyce_www_port = None # port used by spyce web server
+ self.spyce_www_mime = None # files with Apache-like mime type listings
+ self.spyce_www_handler = None # assign handlers by extension
+ # store overides and defaults
+ self.overide_path = overide_path
+ self.overide_import = overide_import
+ self.overide_error = overide_error
+ self.overide_pageerror = overide_pageerror
+ self.overide_globals = overide_globals
+ self.overide_debug = overide_debug
+ self.overide_concurrency = overide_concurrency
+ self.default_concurrency = default_concurrency
+ self.overide_cache = overide_cache
+ self.default_www_root = default_www_root
+ self.overide_www_root = overide_www_root
+ self.default_www_port = default_www_port
+ self.overide_www_port = overide_www_port
+ self.default_www_handler = default_www_handler
+ self.default_www_mime = default_www_mime
+ def process(self):
+ # process (order matters here!)
+ self.processConfigFile()
+ self.processSpycePath()
+ self.processSpyceDebug()
+ self.processSpyceGlobals()
+ self.processSpyceImport()
+ self.processSpyceError()
+ self.processSpyceConcurrency()
+ self.processSpyceCache()
+ self.processSpyceWWW()
+ # accessors
+ def getSpyceHome(self):
+ return SPYCE_HOME
+ def getSpycePath(self):
+ return self.spyce_path
+ def getSpyceImport(self):
+ return self.spyce_import
+ def getSpyceError(self):
+ return self.spyce_error
+ def getSpycePageError(self):
+ return self.spyce_pageerror
+ def getSpyceGlobals(self):
+ return self.spyce_globals
+ def getSpyceDebug(self):
+ return self.spyce_debug
+ def getSpyceConcurrency(self):
+ return self.spyce_concurrency
+ def getSpyceCache(self):
+ return self.spyce_cache
+ def getSpyceWWWRoot(self):
+ return self.spyce_www_root
+ def getSpyceWWWPort(self):
+ return self.spyce_www_port
+ def getSpyceWWWHandler(self):
+ return self.spyce_www_handler
+ def getSpyceWWWMime(self):
+ return self.spyce_www_mime
+ def __repr__(self):
+ return \
+'''path: %(path)s
+import: %(import)s
+error: %(error)s
+globals: %(globals)s
+debug: %(debug)s
+concurrency: %(concurrency)s
+cache: %(cache)s
+www root: %(wwwroot)s
+www port: %(wwwport)s
+www mime: %(wwwmime)s
+www handler: %(wwwhandler)s
+''' % {
+ 'path': self.spyce_path,
+ 'import': self.spyce_import,
+ 'error': self.spyce_error,
+ 'pageerror': self.spyce_pageerror,
+ 'globals': self.spyce_globals,
+ 'debug': self.spyce_debug,
+ 'concurrency': self.spyce_concurrency,
+ 'cache': self.spyce_cache,
+ 'wwwroot': self.spyce_www_root,
+ 'wwwport': self.spyce_www_port,
+ 'wwwmime': self.spyce_www_mime,
+ 'wwwhandler': self.spyce_www_handler,
+}
+
+ # configuration processing
+ def processConfigFile(self):
+ # config file
+ self.spyce_config = {}
+ if not self.file:
+ self.file = self.findConfigFile()
+ if self.file:
+ if not os.path.exists(self.file):
+ raise spyceException.spyceNotFound(self.file)
+ if not os.access(self.file, os.R_OK):
+ raise spyceException.spyceForbidden(self.file)
+ self.spyce_config = self.parseConfigFile()
+ def processSpycePath(self, mod_path=None):
+ def processSpycePathString(str, self=self):
+ dpath = filter(None, map(string.strip, string.split(str, os.pathsep)))
+ for i in range(len(dpath)):
+ dpath[i] = os.path.abspath(dpath[i])
+ self.spyce_path = self.spyce_path + dpath
+ sys.path = sys.path + dpath
+ def filterPath(path):
+ path2 = []
+ for p in path:
+ if p not in path2:
+ path2.append(p)
+ return path2
+ self.spyce_path = [
+ os.path.join(SPYCE_HOME, 'modules'),
+ os.path.join(SPYCE_HOME, 'tags'),
+ ]
+ if mod_path:
+ processSpycePathString(mod_path)
+ if self.spyce_config.has_key('path') and not self.overide_path:
+ processSpycePathString(self.spyce_config['path'])
+ if self.overide_path:
+ processSpycePathString(overide_path)
+ else:
+ if (self.spyce_config and not self.spyce_config.has_key('path')) and os.environ.has_key('SPYCE_PATH'):
+ processSpycePathString(os.environ['SPYCE_PATH'])
+ self.spyce_path = filterPath(self.spyce_path)
+ sys.path = filterPath(sys.path)
+ def processSpyceImport(self):
+ self.spyce_import = []
+ if self.spyce_config.has_key('import'):
+ new_import = filter(None, map(string.strip, string.split(self.spyce_config['import'], ',')))
+ self.spyce_import = self.spyce_import + new_import
+ if self.overide_import:
+ new_import = filter(None, map(string.strip, string.split(self.overide_import, ',')))
+ self.spyce_import = self.spyce_import + new_import
+ for i in self.spyce_import:
+ exec('import %s'%i)
+ def processSpyceError(self):
+ # server-level
+ self.spyce_error = 'error:serverHandler'
+ if self.spyce_config.has_key('error'):
+ self.spyce_error = self.spyce_config['error']
+ if self.overide_error:
+ self.spyce_error = self.overide_error
+ self.spyce_error = string.split(self.spyce_error, ':')
+ if len(self.spyce_error)==1:
+ raise 'invalid error handler specification (file:function)'
+ # page-level
+ self.spyce_pageerror = 'string:error:defaultErrorTemplate'
+ if self.spyce_config.has_key('pageerror'):
+ self.spyce_pageerror = self.spyce_config['pageerror']
+ if self.overide_pageerror:
+ self.spyce_pageerror = self.overide_pageerror
+ self.spyce_pageerror = string.split(self.spyce_pageerror, ':')
+ if (len(self.spyce_pageerror)<2 or self.spyce_pageerror[0] not in ('string', 'file')):
+ raise 'invalid pageerror handler specification ("string":module:variable, or ("file":file)'
+ def processSpyceGlobals(self):
+ self.spyce_globals.clear ()
+ if self.spyce_config.has_key('globals'):
+ for k in self.spyce_config['globals'].keys():
+ self.spyce_globals[k] = self.spyce_config['globals'][k]
+ if self.overide_globals:
+ for k in self.overide_globals.keys():
+ self.spyce_globals[k] = self.overide_globals[k]
+ for k in self.spyce_globals.keys():
+ self.spyce_globals[k] = eval(self.spyce_globals[k])
+ def processSpyceDebug(self):
+ self.spyce_debug = 0
+ if self.spyce_config.has_key('debug'):
+ self.spyce_debug = string.strip(string.lower(self.spyce_config['debug'])) not in ('0', 'false', 'no')
+ if self.overide_debug:
+ self.spyce_debug = 1
+ def processSpyceConcurrency(self):
+ self.spyce_concurrency = SPYCE_CONCURRENCY_SINGLE
+ if self.default_concurrency!=None:
+ self.spyce_concurrency = self.default_concurrency
+ if self.spyce_config.has_key('concurrency'):
+ self.spyce_concurrency = string.lower(self.spyce_config['concurrency'])
+ if self.spyce_concurrency in ('thread', 'threading'):
+ self.spyce_concurrency = SPYCE_CONCURRENCY_THREAD
+ elif self.spyce_concurrency in ('fork', 'forking'):
+ self.spyce_concurrency = SPYCE_CONCURRENCY_FORK
+ else:
+ self.spyce_concurrency = SPYCE_CONCURRENCY_SINGLE
+ if self.overide_concurrency!=None:
+ self.spyce_concurrency = self.overide_concurrency
+ def processSpyceCache(self):
+ cache = 'memory'
+ if self.spyce_config.has_key('cache'):
+ cache = self.spyce_config['cache']
+ cache = string.split(cache, ':')
+ self.spyce_cache = string.strip(string.lower(cache[0])), string.join(cache[1:], ':')
+ def processSpyceWWW(self):
+ # root
+ self.spyce_www_root = self.default_www_root
+ if self.spyce_config.has_key('www_root'):
+ self.spyce_www_root = self.spyce_config['www_root']
+ if self.overide_www_root!=None:
+ self.spyce_www_root = self.overide_www_root
+ # port
+ self.spyce_www_port = self.default_www_port
+ if self.spyce_config.has_key('www_port'):
+ self.spyce_www_port = int(self.spyce_config['www_port'])
+ if self.overide_www_port!=None:
+ self.spyce_www_port = int(self.overide_www_port)
+ # mime
+ self.spyce_www_mime = self.default_www_mime
+ if self.spyce_config.has_key('www_mime'):
+ mime = self.spyce_config['www_mime']
+ mime = map(string.strip, string.split(mime, ','))
+ self.spyce_www_mime = self.spyce_www_mime + mime
+ # handler
+ self.spyce_www_handler = self.default_www_handler
+ if self.spyce_config.has_key('www_handler'):
+ handler = self.spyce_config['www_handler']
+ for k in handler.keys():
+ self.spyce_www_handler[k] = handler[k]
+
+ # helpers
+ def findConfigFile(self):
+ locations = [SPYCE_HOME] + SPYCE_CONFIG_LOCATIONS
+ for l in locations:
+ p = os.path.join(l, SPYCE_CONFIG_FILENAME)
+ if os.path.exists(p):
+ return p
+ def parseConfigFile(self):
+ # initial defaults
+ path = None
+ load = None
+ error = None
+ pageerror = None
+ globals = None
+ debug = None
+ concurrency = None
+ cache = None
+ www_root = None
+ www_port = None
+ www_mime = None
+ www_handler = {}
+ cfg = ConfigParser.ConfigParser()
+ # parse
+ cfg.read(self.file)
+ if cfg.has_section('spyce'):
+ if 'path' in cfg.options('spyce'):
+ path = cfg.get('spyce', 'path')
+ if 'import' in cfg.options('spyce'):
+ load = cfg.get('spyce', 'import')
+ if 'error' in cfg.options('spyce'):
+ error = cfg.get('spyce', 'error')
+ if 'pageerror' in cfg.options('spyce'):
+ pageerror = cfg.get('spyce', 'pageerror')
+ if 'debug' in cfg.options('spyce'):
+ debug = cfg.get('spyce', 'debug')
+ if 'concurrency' in cfg.options('spyce'):
+ concurrency = cfg.get('spyce', 'concurrency')
+ if 'cache' in cfg.options('spyce'):
+ cache = cfg.get('spyce', 'cache')
+ if cfg.has_section('globals'):
+ globals = {}
+ for o in cfg.options('globals'):
+ if o=='__name__': continue
+ globals[o] = cfg.get('globals', o)
+ if cfg.has_section('www'):
+ for o in cfg.options('www'):
+ if o=='__name__': continue
+ if o=='root':
+ www_root = cfg.get('www', o)
+ continue
+ if o=='port':
+ www_port = cfg.get('www', o)
+ continue
+ if o=='mime':
+ www_mime = cfg.get('www', o)
+ continue
+ if o[:len('ext_')]=='ext_':
+ ext = o[len('ext_'):]
+ if not ext: ext = None
+ www_handler[ext] = cfg.get('www', o)
+ # results
+ config = {}
+ if path!=None: config['path'] = path
+ if load!=None: config['import'] = load
+ if error!=None: config['error'] = error
+ if pageerror!=None: config['pageerror'] = pageerror
+ if globals!=None: config['globals'] = globals
+ if debug!=None: config['debug'] = debug
+ if concurrency!=None: config['concurrency'] = concurrency
+ if cache!=None: config['cache'] = cache
+ if www_root!=None: config['www_root'] = www_root
+ if www_port!=None: config['www_port'] = www_port
+ if www_mime!=None: config['www_mime'] = www_mime
+ if www_handler!={}: config['www_handler'] = www_handler
+ return config
diff --git a/system/python/spyce/spyceException.py b/system/python/spyce/spyceException.py
new file mode 100644
index 0000000000..fdb62ff753
--- /dev/null
+++ b/system/python/spyce/spyceException.py
@@ -0,0 +1,116 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+__doc__ = '''Various Spyce-related exceptions'''
+
+import sys, string
+import spyceCompile, spyceUtil
+
+##################################################
+# Syntax errors
+#
+
+class pythonSyntaxError:
+ "Generate string out of current pythonSyntaxError exception"
+ def __repr__(self):
+ return self.str
+ def __init__(self, spycewrap):
+ self.str = ''
+ type, error, _ = sys.exc_info()
+ if type is type(SyntaxError):
+ raise 'instantiate pythonSyntaxError only when SyntaxError raised: %s' % `type`
+ if spycewrap.getCodeRefs().has_key(error.lineno):
+ begin, end, text, filename = spycewrap.getCodeRefs()[error.lineno]
+ if begin[0]==end[0]:
+ linestr = str(begin[0])
+ else:
+ linestr = '%d-%d' % (begin[0], end[0])
+ self.str = 'Python syntax error at %s:%s - %s\n %s\n' % (filename, linestr, error.msg, text)
+ else:
+ self.str = spyceUtil.exceptionString()
+
+class spyceSyntaxError:
+ "Generate string out of current spyceSyntaxError exception"
+ def __init__(self, msg, info=None):
+ self.msg = msg
+ self.info = info
+ def __repr__(self):
+ s = 'Spyce syntax error'
+ if self.info:
+ (begin, _), (end, _), text, filename = self.info
+ if begin==end:
+ linestr = str(begin)
+ else:
+ linestr = '%d-%d' % (begin, end)
+ s = s + ' at %s:%s - %s\n %s\n' % (filename, linestr, self.msg, text)
+ else:
+ s = s + ': '+self.msg
+ return s
+
+##################################################
+# Runtime errors
+#
+
+class spyceRuntimeException:
+ "Generate string out of current SpyceException exception."
+ # useful fields: str, type, value, traceback, msg
+ def __repr__(self):
+ return self.str
+ def __init__(self, spycewrap=None):
+ import traceback, string
+ e1, e2, tb = sys.exc_info()
+ tb = traceback.extract_tb(tb)
+ self.str = ''
+ self.type, self.value, self.traceback = e1, e2, tb
+ if e1 == spyceRuntimeException:
+ self.msg = str(e2)
+ else:
+ self.msg = string.join(traceback.format_exception_only(e1, e2))
+ for i in range(len(tb)):
+ filename, lineno, funcname, text = tb[i]
+ if filename == '<string>' and spycewrap and spycewrap.getCodeRefs().has_key(lineno):
+ if funcname == spyceCompile.SPYCE_PROCESS_FUNC:
+ funcname = '(main)'
+ begin, end, text, filename = spycewrap.getCodeRefs()[lineno]
+ if begin[0]==end[0]:
+ lineno = str(begin[0])
+ else:
+ lineno = '%d-%d' % (begin[0], end[0])
+ lineno=str(lineno)
+ tb[i] = filename, lineno, funcname, text
+ for i in range(len(tb)):
+ self.str = self.str + ' %s:%s, in %s: \n %s\n' % tb[i]
+ self.str = self.str + self.msg
+
+class spyceNotFound:
+ "Exception class to signal that Spyce file does not exist."
+ def __init__(self, file):
+ self.file = file
+ def __repr__(self):
+ return 'spyceNotFound exception: could not find "%s"' % self.file
+
+class spyceForbidden:
+ "Exception class to signal that Spyce file has access problems."
+ def __init__(self, file):
+ self.file = file
+ def __repr__(self):
+ return 'spyceForbidden exception: could not read "%s"' % self.file
+
+##################################################
+# Special control-flow exceptions
+#
+
+class spyceRedirect:
+ "Exception class to signal an internal redirect."
+ def __init__(self, filename):
+ self.filename = filename
+
+class spyceDone:
+ "Exception class to immediately jump to the end of the spyceProcess method"
+ pass
+
diff --git a/system/python/spyce/spyceLock.py b/system/python/spyce/spyceLock.py
new file mode 100644
index 0000000000..61230b2187
--- /dev/null
+++ b/system/python/spyce/spyceLock.py
@@ -0,0 +1,120 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+import os
+
+__doc__ = 'Spyce locking-related functions'
+
+##################################################
+# Generic lock
+#
+
+class genericLock:
+ def lock(self, block=1):
+ "return true, if lock acquired"
+ raise 'not implemented'
+ def unlock(self):
+ raise 'not implemented'
+ def locked(self):
+ raise 'not implemented'
+
+##################################################
+# Dummy lock
+#
+
+class dummyLock(genericLock):
+ def lock(self, block=1):
+ return 1
+ def unlock(self):
+ pass
+ def locked(self):
+ return 0
+
+##################################################
+# Thread locking
+#
+
+class threadLock(genericLock):
+ def __init__(self):
+ import thread
+ self._thelock = thread.allocate_lock()
+ def lock(self, block=1):
+ if block: return self._thelock.acquire()
+ else: return self._thelock.acquire(0)
+ def unlock(self):
+ return self._thelock.release()
+ def locked(self):
+ return self._thelock.locked()
+
+##################################################
+# File locking
+#
+
+# Adapted from portalocker.py, written by Jonathan Feinberg <jdf@pobox.com>
+# Used in rimap (http://rimap.sourceforge.net) before Spyce
+# Methods:
+# file_lock(file, flags)
+# file_unlock(file)
+# Constants: LOCK_EX, LOCK_SH, LOCK_NB
+# -- RB
+
+try:
+ if os.name=='nt':
+ import win32con, win32file, pywintypes
+ LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK
+ LOCK_SH = 0 # the default
+ LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY
+ # is there any reason not to reuse the following structure?
+ __overlapped = pywintypes.OVERLAPPED()
+ def file_lock(file, flags):
+ hfile = win32file._get_osfhandle(file.fileno())
+ win32file.LockFileEx(hfile, flags, 0, 0xffff0000L, __overlapped)
+ def file_unlock(file):
+ hfile = win32file._get_osfhandle(file.fileno())
+ win32file.UnlockFileEx(hfile, 0, 0xffff0000L, __overlapped)
+ elif os.name == 'posix':
+ import fcntl
+ LOCK_EX = fcntl.LOCK_EX
+ LOCK_SH = fcntl.LOCK_SH
+ LOCK_NB = fcntl.LOCK_NB
+ def file_lock(file, flags):
+ fcntl.flock(file.fileno(), flags)
+ def file_unlock(file):
+ fcntl.flock(file.fileno(), fcntl.LOCK_UN)
+ else:
+ raise 'locking not supported on this platform'
+except:
+ LOCK_EX = 0
+ LOCK_SH = 0
+ LOCK_NB = 0
+ # bring on the race conditions! :)
+ def file_lock(file, flags): pass
+ def file_unlock(file): pass
+
+class fileLock(genericLock):
+ f=name=None
+ def __init__(self, name):
+ self.name=name+'.lock'
+ self._locked = 0
+ def lock(self, block=1):
+ self.f=open(self.name, 'w')
+ if block: file_lock(self.f, LOCK_EX)
+ else: file_lock(self.f, LOCK_EX or LOCK_NB)
+ self._locked = 1
+ def unlock(self):
+ try:
+ if not self.f: return
+ file_unlock(self.f)
+ self.f.close()
+ os.unlink(self.name)
+ self.f=None
+ self._locked = 0
+ except: pass
+ def locked(self):
+ return self._locked
+
diff --git a/system/python/spyce/spyceModpy.py b/system/python/spyce/spyceModpy.py
new file mode 100644
index 0000000000..8d63dd1e59
--- /dev/null
+++ b/system/python/spyce/spyceModpy.py
@@ -0,0 +1,138 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+import string, sys, os
+import spyce, spyceException, spyceUtil
+
+__doc__ = '''Apache mod_python-based Spyce entry point.'''
+
+##################################################
+# Request / response handlers
+#
+
+import _apache # fails when not running under apache
+from mod_python import apache
+
+class NoFlush:
+ "Elide flush calls"
+ def __init__(self, apacheRequest):
+ self.write = apacheRequest.write
+ def flush(self):
+ pass
+
+# make sure that both sets of classes have identical functionality
+class spyceModpyRequest(spyce.spyceRequest):
+ "Apache Spyce request object. (see spyce.spyceRequest)"
+ def __init__(self, apacheRequest):
+ spyce.spyceRequest.__init__(self)
+ self._in = apacheRequest
+ def env(self, name=None):
+ return spyceUtil.extractValue(self._in.subprocess_env, name)
+ def getHeader(self, type=None):
+ if type:
+ if self._in.headers_in.has_key(type):
+ return self._in.headers_in[type]
+ else: return self._in.headers_in
+ def getServerID(self):
+ return os.getpid()
+
+class spyceModpyResponse(spyce.spyceResponse):
+ "Apache Spyce response object. (see spyce.spyceResponse)"
+ def __init__(self, apacheRequest):
+ spyce.spyceResponse.__init__(self)
+ self.origout = apacheRequest
+ self.out = spyceUtil.BufferedOutput(NoFlush(apacheRequest))
+ self.isCTset = 0
+ self.headersSent = 0
+ self.returncode = self.origout.status = self.RETURN_OK
+ # functions (for performance)
+ self.write = self.out.write
+ self.writeErr = sys.stderr.write
+ def close(self):
+ self.flush()
+ #self.out.close()
+ def clear(self):
+ self.out.clear()
+ def sendHeaders(self):
+ if self.headersSent:
+ return
+ if not self.isCTset:
+ self.setContentType("text/html")
+ self.origout.send_http_header()
+ self.headersSent = 1
+ def clearHeaders(self):
+ if self.headersSent:
+ raise 'headers already sent'
+ for header in self.origout.headers_out.keys():
+ del self.origout.headers_out[header]
+ def setContentType(self, content_type):
+ if self.headersSent:
+ raise 'headers already sent'
+ self.origout.content_type = content_type
+ self.isCTset = 1
+ def setReturnCode(self, code):
+ if self.headersSent:
+ raise 'headers already sent'
+ self.returncode = self.origout.status = code
+ def addHeader(self, type, data, replace=0):
+ if self.headersSent:
+ raise 'headers already sent'
+ if replace:
+ self.origout.headers_out[type] = data
+ else:
+ self.origout.headers_out.add(type, data)
+ def flush(self, stopFlag=0):
+ if stopFlag: return
+ self.sendHeaders()
+ self.out.flush()
+ def unbuffer(self):
+ self.flush()
+ self.out.unbuffer()
+
+##################################################
+# Apache config
+#
+
+def getApacheConfig(apachereq, param, default=None):
+ "Return Apache mod_python configuration parameter."
+ try:
+ return apachereq.get_options()[param]
+ except:
+ return default
+
+##################################################
+# Apache entry point
+#
+
+CONFIG_FILE = None
+
+def spyceMain(apacheRequest):
+ "Apache entry point."
+ os.environ[spyce.SPYCE_ENTRY] = 'modpy'
+ apacheRequest.add_common_vars()
+ request = spyceModpyRequest(apacheRequest)
+ response = spyceModpyResponse(apacheRequest)
+ filename = apacheRequest.filename
+ global CONFIG_FILE
+ if CONFIG_FILE==None:
+ CONFIG_FILE = getApacheConfig(apacheRequest, 'SPYCE_CONFIG', None)
+ try:
+ result = spyce.spyceFileHandler(request, response, filename, config_file=CONFIG_FILE )
+ except (spyceException.spyceForbidden, spyceException.spyceNotFound), e:
+ response.clear()
+ response.setContentType('text/plain')
+ response.write(str(e)+'\n')
+ except:
+ response.clear()
+ response.setContentType('text/plain')
+ response.write(spyceUtil.exceptionString()+'\n')
+ try:
+ response.flush()
+ except: pass
+ return apache.OK
+
diff --git a/system/python/spyce/spyceModule.py b/system/python/spyce/spyceModule.py
new file mode 100644
index 0000000000..593996b7cd
--- /dev/null
+++ b/system/python/spyce/spyceModule.py
@@ -0,0 +1,55 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+__doc__ = '''Spyce modules functionality.'''
+
+##################################################
+# Spyce module
+#
+
+class spyceModule:
+ "All Spyce module should subclass this."
+ def __init__(self, wrapper):
+ self._api = wrapper
+ def start(self):
+ pass
+ def finish(self, theError=None):
+ pass
+ def init(self, *args, **kwargs):
+ pass
+ def __repr__(self):
+ return 'no information, '+str(self.__class__)
+
+class spyceModulePlus(spyceModule):
+ def __init__(self, wrapper):
+ spyceModule.__init__(self, wrapper)
+ self.wrapper = self._api # deprecated
+ self.modules = moduleFinder(wrapper)
+ self.globals = wrapper.getGlobals()
+
+class moduleFinder:
+ def __init__(self, wrapper):
+ self._wrapper = wrapper
+ def __getattr__(self, name):
+ return self._wrapper.getModule(name)
+
+##################################################
+# Spyce module API
+#
+
+spyceModuleAPI = [ 'getFilename', 'getCode',
+ 'getCodeRefs', 'getModRefs',
+ 'getServerObject', 'getServerGlobals', 'getServerID',
+ 'getModules', 'getModule', 'setModule', 'getGlobals',
+ 'registerModuleCallback', 'unregisterModuleCallback',
+ 'getRequest', 'getResponse', 'setResponse',
+ 'registerResponseCallback', 'unregisterResponseCallback',
+ 'spyceString', 'spyceFile', 'spyceModule', 'spyceTaglib',
+ 'setStdout', 'getStdout',
+]
+
diff --git a/system/python/spyce/spyceTag.py b/system/python/spyce/spyceTag.py
new file mode 100644
index 0000000000..8cb0ec4395
--- /dev/null
+++ b/system/python/spyce/spyceTag.py
@@ -0,0 +1,260 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+__doc__ = '''Spyce tags functionality.'''
+
+import string
+import spyceException, spyceModule
+
+##################################################
+# Spyce tag library
+#
+
+class spyceTagLibrary:
+ "All Spyce tag libraries should subclass this."
+ def __init__(self, prefix):
+ self._prefix = prefix
+ self._taghash = {}
+ for tag in self.tags:
+ self._taghash[tag.name] = tag
+ def getTag(self, name, attrs, paired, parent=None):
+ return self.getTagClass(name)(self._prefix, attrs, paired, parent)
+ def getTagClass(self, name):
+ return self._taghash[name]
+
+ # functions to override
+ tags = []
+ def start(self):
+ pass
+ def finish(self):
+ pass
+
+##################################################
+# Spyce tag
+#
+
+class spyceTag:
+ "All Spyce tags should subclass this."
+ def __init__(self, prefix, attrs, paired, parent=None):
+ "Initialize a tag; prefix = current library prefix"
+ self._prefix = prefix
+ self._attrs = attrs
+ self._pair = paired
+ self._parent = parent
+ self._out = None
+ self._context = None
+ self._buffered = 0
+ # setup tag environment (context and output stream)
+ def setOut(self, out):
+ "Set output stream"
+ self._out = out
+ def setContext(self, context):
+ "Set tag evaluation context"
+ self._context = context
+ def setBuffered(self, buffered):
+ "Set whether tag is running on a buffer wrt. enclosing scope"
+ self._buffered = buffered
+ # accessors
+ def getPrefix(self):
+ "Return tag prefix"
+ return self._prefix
+ def getAttributes(self):
+ "Get tag attributes."
+ return self._attrs
+ def getPaired(self):
+ "Return whether this is a paired or singleton tag."
+ return self._pair
+ def getParent(self, name=None):
+ "Get parent tag"
+ parent = self._parent
+ if name!=None:
+ while parent!=None:
+ if parent._prefix==self._prefix and parent.name==name: break;
+ parent = parent._parent
+ return parent
+ def getOut(self):
+ "Return output stream"
+ return self._out
+ def getContext(self):
+ return self._context
+ def getBuffered(self):
+ "Get whether tag is running on a buffer wrt. enclosing scope"
+ return self._buffered
+ # functions and fields to override
+ "The name of this tag!"
+ name = None
+ "Whether this tag wants to buffer its body processing"
+ buffer = 0
+ "Whether this tag want to conditionally perform body processing"
+ conditional = 0
+ "Whether this tag wants to possibly loop body processing"
+ loops = 0
+ "Whether this tag wants to handle exceptions"
+ catches = 0
+ "Whether end() must (even on exception) get called if begin() completes"
+ mustend = 0
+ def syntax(self):
+ "Check tag syntax"
+ pass
+ def begin(self, **kwargs):
+ "Process start tag; return true to process body (if conditional==1)"
+ return 1
+ def body(self, contents):
+ "Process tag body; return true to repeat (if loops==1)"
+ if contents:
+ self.getOut().write(contents)
+ return 0
+ def end(self):
+ "Process end tag"
+ pass
+ def catch(self, ex):
+ "Process any exception thrown by tag (if catches==1)"
+ raise
+
+class spyceTagPlus(spyceTag):
+ "An easier spyceTag class to work with..."
+ # tag context helpers
+ def contextSet(self, name, (exists, value)):
+ "Set a variable in the context"
+ prev = self.contextGet(name)
+ if exists: self._context[name] = value
+ else: del self._context[name]
+ return prev
+ def contextGet(self, name):
+ "Get a variable from the context"
+ try: return 1, self._context[name]
+ except KeyError: return 0, None
+ def contextEval(self, expr):
+ "Evaluate an expression within the context"
+ if expr and expr[0]=='=':
+ expr = eval(expr[1:], self._context)
+ return expr
+ def contextEvalAttrs(self, attrs):
+ "Evaluate attribute dictionary within context"
+ attrs2 = {}
+ for name in attrs.keys():
+ attrs2[name] = self.contextEval(attrs[name])
+ return attrs2
+ def contextGetModule(self, name):
+ "Return a Spyce module reference"
+ try: return self._context[name]
+ except KeyError:
+ return self._context['taglib']._api.getModule(name)
+
+ # tag syntax checking helpers
+ def syntaxExist(self, *must):
+ "Ensure that certain attributes exist"
+ for attr in must:
+ if not self._attrs.has_key(attr):
+ raise spyceTagSyntaxException('missing compulsory "%s" attribute' % attr)
+ def syntaxExistOr(self, *mustgroups):
+ "Ensure that one of a group of attributes must exist"
+ errors = []
+ success = 0
+ for must in mustgroups:
+ try:
+ if must==type(''): must = (must,)
+ self.apply(self.syntaxExist, must)
+ success = success + 1
+ except spyceTagSyntaxException, e:
+ errors.append(str(e))
+ if not success:
+ raise spyceTagSyntaxException(string.join(errors, ' OR '))
+ def syntaxExistOrEx(self, *mustgroups):
+ success = apply(self.syntaxExistOr, mustgroups)
+ if success > 1:
+ raise spyceTagSyntaxException('only one set of the following groups of tags are allowed: %s', string.join(map(repr, mustgroups), ', '))
+ def syntaxNonEmpty(self, *names):
+ for name in names:
+ try: value = self._attrs[name]
+ except KeyError: return
+ if not value:
+ raise spyceTagSyntaxException('attribute "%s" should not be empty', name)
+ def syntaxValidSet(self, name, validSet):
+ try: value = self._attrs[name]
+ except KeyError: return
+ if value not in validSet:
+ raise spyceTagSyntaxException('attribute "%s" should be one of: %s'% (name, string.join(validSet, ', ')))
+ def syntaxPairOnly(self):
+ "Ensure that this tag is paired i.e. open/close"
+ if not self._pair:
+ raise spyceTagSyntaxException('singleton tag not allowed')
+ def syntaxSingleOnly(self):
+ "Ensure that this tag is single i.e. <foo/>"
+ if self._pair:
+ raise spyceTagSyntaxException('paired tag not allowed')
+
+
+##################################################
+# Spyce tag syntax checking
+#
+
+class spyceTagChecker:
+ def __init__(self, server):
+ self._server = server
+ self._taglibs = {}
+ self._stack = []
+ def loadLib(self, libname, libfrom, libas, rel_file, info=None):
+ if not libas: libas = libname
+ try:
+ self._taglibs[(libname, libfrom)] = \
+ self._server.loadModule(libname, libfrom, rel_file)(libas)
+ except (SyntaxError, TypeError):
+ raise
+ except:
+ raise spyceException.spyceSyntaxError(
+ 'unable to load module: %s'%libname, info)
+ def getTag(self, (libname,libfrom), name, attrs, pair, info):
+ lib = self._taglibs[(libname, libfrom)]
+ try:
+ return lib.getTag(name, attrs, pair, None)
+ except:
+ raise spyceException.spyceSyntaxError(
+ 'unknown tag "%s:%s"'%(libname, name), info)
+ def getTagClass(self, (libname, libfrom), name, info):
+ lib = self._taglibs[(libname, libfrom)]
+ try:
+ return lib.getTagClass(name)
+ except:
+ raise spyceException.spyceSyntaxError(
+ 'unknown tag "%s:%s"'%(libname, name), info)
+ def startTag(self, (libname,libfrom), name, attrs, pair, info):
+ tag = self.getTag((libname, libfrom), name, attrs, pair, info)
+ try:
+ error = tag.syntax()
+ except spyceTagSyntaxException, e:
+ raise spyceException.spyceSyntaxError(str(e), info)
+ if error:
+ raise spyceException.spyceSyntaxError(error, info)
+ if pair:
+ self._stack.append( (libname, libfrom, name, info) )
+ def endTag(self, (libname,libfrom), name, info):
+ try:
+ libname1, libfrom1, name1, info1 = self._stack.pop()
+ except IndexError:
+ raise spyceException.spyceSyntaxError(
+ 'unmatched close tag', info)
+ if (libname1,libfrom1,name1) != (libname,libfrom,name):
+ raise spyceException.spyceSyntaxError(
+ 'unmatched close tag, expected <%s:%s>' % (libname1,name1), info)
+ def finish(self):
+ if self._stack:
+ libname, libfrom, name, info = self._stack.pop()
+ raise spyceException.spyceSyntaxError(
+ 'unmatched open tag', info)
+
+##################################################
+# Spyce tag syntax exception
+#
+
+class spyceTagSyntaxException:
+ def __init__(self, str):
+ self._str = str
+ def __repr__(self):
+ return self._str
+
diff --git a/system/python/spyce/spyceUtil.py b/system/python/spyce/spyceUtil.py
new file mode 100644
index 0000000000..2fc0a9e98b
--- /dev/null
+++ b/system/python/spyce/spyceUtil.py
@@ -0,0 +1,157 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+import sys, re, string
+from cStringIO import StringIO
+
+__doc__ = '''Spyce utility functions'''
+
+##################################################
+# Current exception string
+#
+
+def exceptionString():
+ "Generate string out of current exception."
+ import traceback, string
+ ex=sys.exc_info()
+ ex=traceback.format_exception(ex[0], ex[1], ex[2])
+ ex=string.join(ex, '')
+ return ex
+
+##################################################
+# Return hashtable value, or entire hashtable
+#
+
+def extractValue(hash, key, default=None):
+ """Extract value from dictionary, if it exists.
+ If key is none, return entire dictionary"""
+ if key==None: return hash
+ if hash.has_key(key): return hash[key]
+ return default
+
+##################################################
+# Return hashtable value, or entire hashtable
+#
+
+RE_SPACE_REDUCE = re.compile('[ \t][ \t]+')
+RE_SPACE_NEWLINE_REDUCE = re.compile('\n\s+')
+def spaceCompact(text):
+ text = string.split(text, '\n')
+ text = map(lambda s: RE_SPACE_REDUCE.sub(' ', s), text)
+ text = string.join(text, '\n')
+ text = RE_SPACE_NEWLINE_REDUCE.sub('\n', text)
+ return text
+
+##################################################
+# Threading helpers
+#
+
+class ThreadedWriter:
+ '''Thread-safe writer'''
+ def __init__(self, o=None):
+ try: import thread,threading
+ except: raise 'threading not supported!'
+ self.__dict__['_currentThread'] = threading.currentThread
+ self.__dict__['_o'] = o
+ def setObject(self, o=None):
+ self._currentThread().threadOut = o
+ self._currentThread().threadWrite = o.write
+ def getObject(self):
+ try: return self._currentThread().threadOut
+ except AttributeError: return self._o
+ def clearObject(self):
+ try: del self._currentThread().threadOut
+ except AttributeError: pass
+ def write(self, s):
+ try: self._currentThread().threadWrite(s)
+ except AttributeError: self._o.write(s)
+ def close(self):
+ self.getObject().close()
+ def flush(self):
+ self.getObject().flush()
+ def __getattr__(self, name):
+ if name=='softspace': # performance
+ return self.getObject().softspace
+ return eval('self.getObject().%s'%name)
+ def __setattr__(self, name, value):
+ if name=='softspace': # performance
+ self.getObject().softspace = value
+ eval('self.getObject().%s=value'%name)
+ def __delattr__(self, name):
+ return eval('del self.getObject().%s'%name)
+
+##################################################
+# Output
+#
+
+class BufferedOutput:
+ "Buffered output stream."
+ def __init__(self, out):
+ self.buf = StringIO()
+ self.writeBuf = self.buf.write
+ self.out = out
+ self.closed = 0
+ def write(self, s):
+ if self.closed:
+ raise 'output stream closed'
+ self.writeBuf(s)
+ def clear(self):
+ if not self.buf:
+ raise 'stream is not buffered'
+ self.buf = StringIO()
+ self.writeBuf = self.buf.write
+ def flush(self, stopFlag=0):
+ if stopFlag: return
+ if self.buf and self.buf.getvalue():
+ self.out.write(self.buf.getvalue())
+ self.out.flush()
+ self.clear()
+ def close(self):
+ if self.closed:
+ raise 'output stream closed'
+ self.closed = 1
+ self.flush()
+ self.out.close()
+ def unbuffer(self):
+ "Turn this into a pass-through."
+ if self.buf:
+ self.flush()
+ self.buf = None
+ self.writeBuf = self.out.write
+ def getOut(self):
+ "Return underlying output stream."
+ return self.out
+
+
+class NoCloseOut:
+ def __init__(self, out):
+ self.out = out
+ self.write = self.out.write
+ self.flush = self.out.flush
+ def close(self):
+ pass
+ def getOut(self):
+ return self.out
+
+def panicOutput(response, s):
+ import cgi
+ # output to browser, if possible
+ try: response.clear()
+ except: pass
+ try:
+ response.write('<html><pre>\n')
+ response.write('Spyce Panic!<br>\n')
+ response.write(cgi.escape(s))
+ response.write('</pre></html>\n')
+ response.returncode = response.RETURN_OK
+ response.flush()
+ except: pass
+ # output to error log
+ sys.stderr.write(s)
+ sys.stderr.flush()
+ sys.exit(1)
diff --git a/system/python/spyce/spyceWWW.py b/system/python/spyce/spyceWWW.py
new file mode 100644
index 0000000000..0ba5d28b42
--- /dev/null
+++ b/system/python/spyce/spyceWWW.py
@@ -0,0 +1,324 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+import sys, os, string, socket, BaseHTTPServer, SocketServer, cgi, stat, time
+import spyce, spyceConfig, spyceException, spyceCmd, spyceUtil
+
+__doc__ = '''Self-standing Spyce web server.'''
+
+LOG = 1
+
+def formatBytes(bytes):
+ bytes = float(bytes)
+ if bytes<=9999: return "%6.0f" % bytes
+ bytes = bytes / float(1024)
+ if bytes<=999: return "%5.1fK" % bytes
+ bytes = bytes / float(1024)
+ return "%5.1fM" % bytes
+
+##################################################
+# Request / response handlers
+#
+
+class spyceHTTPRequest(spyce.spyceRequest):
+ 'HTTP Spyce request object. (see spyce.spyceRequest)'
+ def __init__(self, httpdHandler, documentRoot):
+ spyce.spyceRequest.__init__(self)
+ self._in = httpdHandler.rfile
+ self._headers = httpdHandler.headers
+ self._httpdHandler = httpdHandler
+ self._documentRoot = documentRoot
+ self._env = None
+ def env(self, name=None):
+ if not self._env:
+ self._env = {
+ 'REMOTE_ADDR': self._httpdHandler.client_address[0],
+ 'REMOTE_PORT': self._httpdHandler.client_address[1],
+ 'GATEWAY_INTERFACE': "CGI/1.1",
+ 'REQUEST_METHOD': self._httpdHandler.command,
+ 'REQUEST_URI': self._httpdHandler.path,
+ 'PATH_INFO': self._httpdHandler.pathinfo,
+ 'SERVER_SOFTWARE': 'spyce/%s' % spyce.__version__,
+ 'SERVER_PROTOCOL': self._httpdHandler.request_version,
+ # 'SERVER_ADDR' ... '127.0.0.1'
+ # 'SERVER_PORT' ... '80'
+ # 'SERVER_NAME' ... 'mymachine.mydomain.com'
+ # 'SERVER_SIGNATURE' ... ' Apache/1.3.22 Server at mymachine.mydomain.com Port 80'
+ # 'SERVER_ADMIN'] ... 'rimon@acm.org'
+ 'DOCUMENT_ROOT': self._documentRoot,
+ 'QUERY_STRING':
+ string.join(string.split(self._httpdHandler.path, '?')[1:]) or '',
+ 'CONTENT_LENGTH': self.getHeader('Content-Length'),
+ 'CONTENT_TYPE': self.getHeader('Content-type'),
+ 'HTTP_USER_AGENT': self.getHeader('User-Agent'),
+ 'HTTP_ACCEPT': self.getHeader('Accept'),
+ 'HTTP_ACCEPT_ENCODING': self.getHeader('Accept-Encoding'),
+ 'HTTP_ACCEPT_LANGUAGE': self.getHeader('Accept-Language'),
+ 'HTTP_ACCEPT_CHARSET': self.getHeader('Accept-Charset'),
+ 'HTTP_COOKIE': self.getHeader('Cookie'),
+ 'HTTP_REFERER': self.getHeader('Referer'),
+ 'HTTP_HOST': self.getHeader('Host'),
+ 'HTTP_CONNECTION': self.getHeader('Connection'),
+ 'HTTP_KEEP_ALIVE': self.getHeader('Keep-alive'),
+ # From ASP
+ # AUTH_TYPE,
+ # APPL_PHYSICAL_PATH,
+ # REMOTE_HOST,
+ # SERVER_PROTOCOL,
+ # SERVER_SOFWARE
+ }
+ return spyceUtil.extractValue(self._env, name)
+ def getHeader(self, type=None):
+ if type: type=string.lower(type)
+ return spyceUtil.extractValue(self._headers.dict, type)
+ def getServerID(self):
+ return os.getpid()
+
+class spyceHTTPResponse(spyceCmd.spyceCmdlineResponse):
+ 'HTTP Spyce response object. (see spyce.spyceResponse)'
+ def __init__(self, httpdHandler):
+ self._httpheader = httpdHandler.request_version!='HTTP/0.9'
+ spyceCmd.spyceCmdlineResponse.__init__(self, spyceUtil.NoCloseOut(httpdHandler.wfile), sys.stdout, self._httpheader)
+ self._httpdHandler = httpdHandler
+ # incidentally, this a rather expensive operation!
+ if LOG:
+ httpdHandler.log_request()
+ def sendHeaders(self):
+ if self._httpheader and not self.headersSent:
+ resultText = spyceUtil.extractValue(self.RETURN_CODE, self.returncode)
+ self.origout.write('%s %s %s\n' % (self._httpdHandler.request_version, self.returncode, resultText))
+ spyceCmd.spyceCmdlineResponse.sendHeaders(self)
+ def close(self):
+ spyceCmd.spyceCmdlineResponse.close(self)
+ self._httpdHandler.request.close()
+
+
+##################################################
+# Spyce web server
+#
+
+class myHTTPhandler(BaseHTTPServer.BaseHTTPRequestHandler):
+ def do_GET(self):
+ try:
+ # parse pathinfo
+ pathinfo = os.path.normpath(string.split(self.path, '?')[0])
+ while pathinfo and (pathinfo[0]==os.sep or pathinfo[0:2]==os.pardir):
+ if pathinfo[0:len(os.sep)]==os.sep: pathinfo=pathinfo[len(os.sep):]
+ if pathinfo[0:len(os.pardir)]==os.pardir: pathinfo=pathinfo[len(os.pardir):]
+ self.pathinfo = "/"+pathinfo
+ # convert to path
+ path = os.path.join(self.server.documentRoot, pathinfo)
+ # directory listing
+ if os.path.isdir(path):
+ return self.handler_dir(path)
+ # search up path (path_info)
+ while len(path)>len(self.server.documentRoot) and not os.path.exists(path):
+ path, _ = os.path.split(path)
+ # for files (or links), find appropriate handler
+ if os.path.isfile(path) or os.path.islink(path):
+ _, ext = os.path.splitext(path)
+ if ext: ext = ext[1:]
+ try:
+ handler = self.server.handler[ext]
+ except:
+ handler = self.server.handler[None]
+ # process request
+ return handler(self, path)
+ # invalid path
+ self.send_error(404, "Invalid path")
+ return None
+ except IOError:
+ self.send_error(404, "Unexpected IOError")
+ return None
+ do_POST=do_GET
+ def handler_spyce(self, path):
+ # process spyce
+ request = spyceHTTPRequest(self, self.server.documentRoot)
+ response = spyceHTTPResponse(self)
+ result = spyce.spyceFileHandler(request, response, path)
+ response.close()
+ def handler_dump(self, path):
+ # process content to dump (with correct mime type)
+ f = None
+ try:
+ try:
+ f = open(path, 'rb')
+ except IOError:
+ self.send_error(404, "No permission to open file")
+ return None
+ try:
+ _, ext = os.path.splitext(path)
+ if ext: ext=ext[1:]
+ mimetype = self.server.mimeTable[ext]
+ except:
+ mimetype = "application/octet-stream"
+ self.send_response(200)
+ self.send_header("Content-type", mimetype)
+ self.end_headers()
+ self.wfile.write(f.read())
+ self.request.close()
+ finally:
+ try:
+ if f: f.close()
+ except: pass
+ def handler_dir(self, path):
+ # process directory
+ if(self.path[-1:]!='/'):
+ self.send_response(301)
+ self.send_header('Location', self.path+'/')
+ self.end_headers()
+ return
+ try:
+ list = os.listdir(path)
+ except os.error:
+ self.send_error(404, "Path does not exist")
+ return None
+ list.sort(lambda a, b: cmp(a.lower(), b.lower()))
+ def info(name, path=path):
+ fullname = os.path.join(path, name)
+ displayname = linkname = name = cgi.escape(name)
+ # Append / for directories or @ for symbolic links
+ if os.path.isdir(fullname):
+ displayname = name + "/"
+ linkname = name + "/"
+ elif os.path.islink(fullname):
+ displayname = name + "@"
+ statinfo = os.stat(fullname)
+ mtime = statinfo[stat.ST_MTIME]
+ size = statinfo[stat.ST_SIZE]
+ return linkname, displayname, mtime, size
+ list = map(info, list)
+
+ NAME_WIDTH = 30
+ output = '''
+<html><head>
+ <title>Index of %(title)s</title>
+</head>
+<body>
+<h1>Index of /%(title)s</h1>
+<pre> Name%(filler)s Date%(filler_date)s Size<hr/>''' % {
+ 'title' : self.pathinfo,
+ 'filler': ' '*(NAME_WIDTH-len('Name')),
+ 'filler_date': ' '*(len(time.asctime(time.localtime(0)))-len('Date')),
+ }
+
+ if list:
+ for link, display, mtime, size in list:
+ output = output + ' <a href="%(link)s">%(display)s</a>%(filler)s %(mtime)s %(size)s\n' % {
+ 'link': link,
+ 'display': display[:NAME_WIDTH],
+ 'link': link,
+ 'filler': ' '*(NAME_WIDTH-len(display)),
+ 'mtime': time.asctime(time.localtime(mtime)),
+ 'size': formatBytes(size),
+ }
+ else:
+ output = output + 'No files\n'
+
+ output = output[:-1] + '''<hr/></pre>
+<address>Spyce-WWW/%(version)s server</address>
+</body></html>
+''' % {
+ 'version' : spyce.__version__,
+ }
+ self.send_response(200)
+ self.send_header("Content-type", "text/html")
+ self.end_headers()
+ self.wfile.write(output)
+
+def buildMimeTable(files):
+ mimetable = {}
+ for file in files:
+ try:
+ f = None
+ try:
+ f = open(file, 'r')
+ print "# MIME file: "+file
+ line = f.readline()
+ while line:
+ if line[0]=='#':
+ line = f.readline(); continue
+ line = string.strip(line)
+ if not line:
+ line = f.readline(); continue
+ line = string.replace(line, '\t', ' ')
+ items = filter(None, map(string.strip, string.split(line, ' ')))
+ mimetype, extensions = items[0], items[1:]
+ for ext in extensions:
+ mimetable[ext] = mimetype
+ line = f.readline()
+ except IOError: pass
+ finally:
+ try:
+ if f: f.close()
+ except: pass
+ return mimetable
+
+def buildHandlerTable(handler, server):
+ for ext in handler.keys():
+ handler[ext] = eval('server.handler_'+handler[ext])
+ return handler
+
+def spyceHTTPserver(port, root, config_file=None, daemon=None):
+ os.environ[spyce.SPYCE_ENTRY] = 'www'
+ spyceCmd.showVersion()
+ print '# Starting web server'
+ # test for threading support, if needed
+ try:
+ server = spyce.getServer(
+ config_file=config_file,
+ overide_www_port=port,
+ overide_www_root=root)
+ except (spyceException.spyceForbidden, spyceException.spyceNotFound), e:
+ print e
+ return
+ if server.concurrency==spyceConfig.SPYCE_CONCURRENCY_THREAD:
+ spyceUtil.ThreadedWriter() # will raise exception if 'import thread' fails
+ # determine type of server concurrency
+ serverSuperClass = {
+ spyceConfig.SPYCE_CONCURRENCY_SINGLE: SocketServer.TCPServer,
+ spyceConfig.SPYCE_CONCURRENCY_FORK: SocketServer.ForkingTCPServer,
+ spyceConfig.SPYCE_CONCURRENCY_THREAD: SocketServer.ThreadingTCPServer,
+ } [server.concurrency]
+ class sharedSocketServer(serverSuperClass):
+ def server_bind(self):
+ self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ SocketServer.TCPServer.server_bind(self)
+ try:
+ # initialize server
+ try:
+ httpd = sharedSocketServer(('',server.config.getSpyceWWWPort()), myHTTPhandler)
+ print '# Server Port: %d' % server.config.getSpyceWWWPort()
+ httpd.documentRoot = os.path.abspath(server.config.getSpyceWWWRoot())
+ print '# Server Root: '+httpd.documentRoot
+ httpd.mimeTable = buildMimeTable(server.config.getSpyceWWWMime())
+ httpd.handler = buildHandlerTable(server.config.getSpyceWWWHandler(), myHTTPhandler)
+ except:
+ print 'Unable to start server on port %s' % server.config.getSpyceWWWPort()
+ return -1
+ # daemonize
+ if daemon:
+ print '# Daemonizing process.'
+ try:
+ spyceCmd.daemonize(pidfile=daemon)
+ except SystemExit: # expected
+ return 0
+ global LOG
+ LOG = 0
+ # process requests
+ print '# Ready.'
+ while 1:
+ try:
+ httpd.handle_request()
+ except KeyboardInterrupt: raise
+ except:
+ print 'Error: %s' % spyceUtil.exceptionString()
+ except KeyboardInterrupt:
+ print 'Break!'
+ return 0
+
diff --git a/system/python/spyce/spyceXbmc.py b/system/python/spyce/spyceXbmc.py
new file mode 100644
index 0000000000..6b807a7216
--- /dev/null
+++ b/system/python/spyce/spyceXbmc.py
@@ -0,0 +1,25 @@
+import sys, os
+sys.path.append(sys.executable + '\\spyce')
+from StringIO import StringIO
+import spyce, spyceCmd, string
+
+def ParseFile(file, env):
+ output = StringIO()
+ input = StringIO(env['QUERY_STRING'])
+ env['REQUEST_URI'] = "/" + string.replace(string.lstrip(file, "Q:\\web"), "\\", "/")
+ SPYCE_HOME = os.path.abspath(os.path.dirname(sys.modules['spyceXbmc'].__file__))
+ request = spyceCmd.spyceCmdlineRequest(input, env, file)
+ response = spyceCmd.spyceCmdlineResponse(output, sys.stderr, 1)
+ result = spyce.spyceFileHandler(request, response, file)
+ response.flush()
+ result = output.getvalue()
+ response.close()
+ return result
+
+if __name__ == '__main__':
+ file = 'docs\\examples\\hello.spy'
+ if os.access(file, os.F_OK):
+ print(ParseFile(file))
+ else:
+ print('file not found')
+
diff --git a/system/python/spyce/tree.py b/system/python/spyce/tree.py
new file mode 100644
index 0000000000..d4fb51f1e3
--- /dev/null
+++ b/system/python/spyce/tree.py
@@ -0,0 +1,70 @@
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+import string
+
+class tree:
+ def __init__(self, data):
+ self.data = data
+ self.parent = None
+ self.children = []
+ self.next = self.prev = None
+ self.depth = 0
+ def append(self, data):
+ node = tree(data)
+ self.children.append(node)
+ node.parent = self
+ node.depth = self.depth+1
+ return node
+ def delete(self):
+ for c in self.children:
+ c.delete()
+ if self.parent:
+ self.parent.children.remove(self)
+ self.parent = None
+ def __repr__(self):
+ return '%s [%s]' % (self.data, string.join(map(str, self.children),', '))
+ def postWalk(self, f):
+ for c in self.children:
+ c.postWalk(f)
+ f(self)
+ def preWalk(self, f):
+ f(self)
+ for c in self.children:
+ c.preWalk(f)
+ def computePreChain(self):
+ prev = [None]
+ def walker(node, prev=prev):
+ node.prev = prev[0]
+ if prev[0]:
+ node.prev.next = node
+ prev[0] = node
+ self.preWalk(walker)
+ def __cmp__(self, o):
+ try:
+ x = not self.data == o.data
+ if x: return x
+ x = not self.children == o.children
+ if x: return x
+ except:
+ return 1
+ return 0
+
+if __name__=='__main__':
+ root = tree('1')
+ n = root.append('1.1')
+ n.append('1.1.1')
+ n = root.append('1.2')
+ n.append('1.2.1')
+ root.computePreChain()
+ n = root
+ while(n):
+ print n.data
+ n = n.next
+ root.delete()
+
diff --git a/system/python/spyce/verchk.py b/system/python/spyce/verchk.py
new file mode 100755
index 0000000000..8ebfe8791f
--- /dev/null
+++ b/system/python/spyce/verchk.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+
+##################################################
+# SPYCE - Python-based HTML Scripting
+# Copyright (c) 2002 Rimon Barr.
+#
+# Refer to spyce.py
+# CVS: $Id$
+##################################################
+
+__doc__ = '''Version checking script.'''
+
+import sys, os
+
+REQUIRED = '1.5'
+
+def checkversion(required):
+ if int(sys.version[0])<int(required[0]) or \
+ (sys.version[0]==required[0] and int(sys.version[2])<int(required[2])):
+ return 0
+ return 1
+
+if __name__ == "__main__":
+ if not checkversion(REQUIRED):
+ print 'Python version '+REQUIRED+' required.'
+ sys.exit(-1)
+ if len(sys.argv)<2:
+ print 'Python version '+sys.version[:3]+' - OK'
+ else:
+ #sys.argv[1] = os.path.join(os.path.dirname(sys.argv[0]), sys.argv[1])
+ del sys.argv[0]
+ if not os.path.exists(sys.argv[0]):
+ print 'Script "'+sys.argv[0]+'" not found.'
+ sys.exit(-1)
+ execfile(sys.argv[0])
+
diff --git a/system/scrapers/music/allmusic.gif b/system/scrapers/music/allmusic.gif
new file mode 100644
index 0000000000..30c40ef318
--- /dev/null
+++ b/system/scrapers/music/allmusic.gif
Binary files differ
diff --git a/system/scrapers/music/allmusic.xml b/system/scrapers/music/allmusic.xml
new file mode 100644
index 0000000000..9a3a9019f6
--- /dev/null
+++ b/system/scrapers/music/allmusic.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.1" date="2009-09-20" name="Allmusic" content="albums" thumb="allmusic.gif" language="en">
+ <include>common/htbackdrops.xml</include>
+ <include>common/allmusic.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Fanart&quot; type=&quot;bool&quot; id=&quot;htbfanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Grab thumbs from HTBackdrops&quot; type=&quot;bool&quot; id=&quot;htbthumbs&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="\1" dest="3">
+ <expression>(http://www.allmusic.com/cg/.*)</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateAlbumSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url post=&quot;yes&quot;&gt;http://www.allmusic.com/cg/amg.dll?P=amg&amp;amp;SQL=\1&amp;amp;OPT1=2&lt;/url&gt;" dest="3">
+ <expression></expression>
+ </RegExp>
+ </CreateAlbumSearchUrl>
+ <GetAlbumSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\1&lt;/title&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes" noclean="1">&lt;TITLE&gt;allmusic[ (]+ ([^&gt;]*) &gt; Overview</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;year&gt;\1&lt;/year&gt;&lt;artist&gt;\2&lt;/artist&gt;&lt;title&gt;\4&lt;/title&gt;&lt;url cache=&quot;am-\2-\4-album.html&quot;&gt;http://www.allmusic.com/cg/amg.dll?p=amg&amp;amp;SQL=\3&lt;/url&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes" noclean="1,2,3">&gt;([0-9]+)&lt;/.*?&gt;([a-zA-Z0-9].*?)&lt;.*?sql=([0-9:a-z]*)&quot;&gt;(.*?)&lt;.</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetAlbumSearchResults>
+ <GetAlbumDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;url cache=&quot;am-$$2-album.html&quot; function=&quot;ParseAMGAlbum&quot;&gt;http://www.allmusic.com/cg/amg.dll?p=amg&amp;amp;sql=\1&lt;/url&gt;" dest="5+">
+ <expression noclean="1">sql=([^&quot;]*)&quot;&gt;Overview</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url cache=&quot;am-$$2-album.html&quot; function=&quot;GetAMGReview&quot;&gt;http://www.allmusic.com/cg/amg.dll?p=amg&amp;amp;sql=\1&lt;/url&gt;" dest="5+">
+ <expression noclean="1">sql=([^&quot;]*)&quot;&gt;Review</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetAlbumDetails>
+ <CreateArtistSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url post=&quot;yes&quot;&gt;http://www.allmusic.com/cg/amg.dll?P=amg&amp;amp;SQL=\1&amp;amp;OPT1=1&lt;/url&gt;" dest="3">
+ <expression></expression>
+ </RegExp>
+ </CreateArtistSearchUrl>
+ <GetArtistSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\1&lt;/title&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes" noclean="1">&lt;TITLE&gt;allmusic[ (]+ ([^&gt;]*) &gt; Overview</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;genre&gt;\3&lt;/genre&gt;&lt;year&gt;\5&lt;/year&gt;&lt;url cache=&quot;am-\2-artist.html&quot;&gt;http://www.allmusic.com/cg/amg.dll?p=amg&amp;amp;SQL=\1&lt;/url&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes" noclean="1,2">style=&quot;[^=]*&lt;a href=&quot;[^&quot;]*sql=([^&quot;]*)&quot;&gt;([^&lt;]*)&lt;/a&gt;[^-]*[^&gt;]*&gt;([^&lt;]*)&lt;/TD&gt;[^&gt;]*&gt;(&amp;nbsp;)?([^&lt;]*)&lt;/td&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetArtistSearchResults>
+ <GetArtistDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;url cache=&quot;am-$$2-artist.html&quot; function=&quot;ParseAMGArtist&quot;&gt;http://www.allmusic.com/cg/amg.dll?p=amg&amp;amp;sql=\1&lt;/url&gt;" dest="5">
+ <expression noclean="1">sql=([^&quot;]*)&quot;&gt;Biography</expression>
+ </RegExp>
+ <RegExp input="$$2" conditional="htbthumbs" output="&lt;url function=&quot;GetHTBThumbs&quot; post=&quot;yes&quot;&gt;http://www.htbackdrops.com/search.php?search_terms=all&amp;amp;cat_id=5&amp;amp;search_keywords=\1&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp input="$$2" conditional="htbfanart" output="&lt;url function=&quot;GetHTBFanart&quot; post=&quot;yes&quot;&gt;http://www.htbackdrops.com/search.php?search_terms=all&amp;amp;cat_id=1&amp;amp;search_keywords=\1&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url cache=&quot;am-$$2-artist.html&quot; function=&quot;GetAMGBiography&quot;&gt;http://www.allmusic.com/cg/amg.dll?p=amg&amp;amp;sql=\1&lt;/url&gt;" dest="5+">
+ <expression noclean="1">sql=([^&quot;]*)&quot;&gt;Biography</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url cache=&quot;am-$$2-discog.html&quot; function=&quot;GetAMGDiscography&quot;&gt;http://www.allmusic.com/cg/amg.dll?p=amg&amp;amp;sql=\1&lt;/url&gt;" dest="5+">
+ <expression noclean="1">sql=([^&quot;]*)&quot;&gt;Discography</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetArtistDetails>
+</scraper>
diff --git a/system/scrapers/music/allmusic_merlin_lastfm.xml b/system/scrapers/music/allmusic_merlin_lastfm.xml
new file mode 100644
index 0000000000..a7b30d7b85
--- /dev/null
+++ b/system/scrapers/music/allmusic_merlin_lastfm.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.1" date="2009-09-16" name="allmusic &amp; merlin.pl &amp; lastfm.pl" content="albums" thumb="allmusic.gif">
+ <include>common/htbackdrops.xml</include>
+ <include>common/allmusic.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Fanart&quot; type=&quot;bool&quot; id=&quot;htbfanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Grab thumbs from HTBackdrops&quot; type=&quot;bool&quot; id=&quot;htbthumbs&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="\1" dest="3">
+ <expression>(http://www.allmusic.com/cg/.*)</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateAlbumSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url post=&quot;yes&quot;&gt;http://www.allmusic.com/cg/amg.dll?P=amg&amp;amp;SQL=\1&amp;amp;OPT1=2&lt;/url&gt;" dest="3">
+ <expression></expression>
+ </RegExp>
+ </CreateAlbumSearchUrl>
+ <GetAlbumSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\1&lt;/title&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes" noclean="1">&lt;TITLE&gt;allmusic[ (]+ ([^&gt;]*) &gt; Overview</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;year&gt;\1&lt;/year&gt;&lt;artist&gt;\2&lt;/artist&gt;&lt;title&gt;\4&lt;/title&gt;&lt;url cache=&quot;allmusic-album.html&quot;&gt;http://www.allmusic.com/cg/amg.dll?p=amg&amp;amp;SQL=\3&lt;/url&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes" noclean="1,2,3">&gt;([0-9]+)&lt;/.*?&gt;([a-zA-Z0-9].*?)&lt;.*?sql=([0-9:a-z]*)&quot;&gt;(.*?)&lt;.</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetAlbumSearchResults>
+ <GetAlbumDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;url cache=&quot;allmusic-album.html&quot; function=&quot;ParseAMGAlbum&quot;&gt;placeholder&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression noclean="1">&lt;TITLE&gt;allmusic[ (]+ ([^&gt;]*) &gt; Overview</expression>
+ </RegExp>
+ <RegExp input="$$9" output="\1" dest="6">
+ <RegExp input="$$8" output="+\1" dest="9">
+ <expression repeat="yes">([^ ]+)</expression>
+ </RegExp>
+ <expression>\+(.*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression noclean="1">&lt;span&gt;Artist&lt;/span&gt;[^;]*[^&gt;]*&gt;[^&gt;]*&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="\1" dest="7">
+ <RegExp input="$$8" output="+\1" dest="9">
+ <expression repeat="yes">([^ ]+)</expression>
+ </RegExp>
+ <expression>\+(.*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;MerlinLink&quot;&gt;http://merlin.pl/xbmc/browse/search/4,,1.html?phrase=&amp;amp;place=4+simple&amp;amp;carrier=3&amp;amp;offer=O&amp;amp;category=&amp;amp;title=$$6&amp;amp;person=$$7&amp;amp;firm=&amp;amp;date=&amp;amp;isbn=&amp;amp;sort=rank&amp;amp;x=40&amp;amp;y=12&lt;/url&gt;" dest="5+">
+ <expression noclean="1"></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetAlbumDetails>
+ <MerlinLink dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;url function=&quot;GetReview&quot;&gt;http://merlin.pl\1&lt;/url&gt;" dest="2">
+ <expression>Liczba towar[^f]+f=&quot;([^&quot;]+)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </MerlinLink>
+ <GetReview dest="5">
+ <RegExp input="$$2" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-2&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;&lt;review&gt;\1&lt;/review&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="2">
+ <expression>class=&quot;productDesc&quot;&gt;(.*?)&lt;/div&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="2+">
+ <expression>piorka_merlina.*?contents&quot;&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="2+">
+ <expression>contents&quot;&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetReview>
+ <CreateArtistSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url post=&quot;yes&quot;&gt;http://www.allmusic.com/cg/amg.dll?P=amg&amp;amp;SQL=\1&amp;amp;OPT1=1&lt;/url&gt;" dest="3">
+ <expression></expression>
+ </RegExp>
+ </CreateArtistSearchUrl>
+ <GetArtistSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\1&lt;/title&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes" noclean="1">&lt;TITLE&gt;allmusic[ (]+ ([^&gt;]*) &gt; Overview</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;genre&gt;\3&lt;/genre&gt;&lt;year&gt;\5&lt;/year&gt;&lt;url cache=&quot;allmusic-artist.html&quot; &gt;http://www.allmusic.com/cg/amg.dll?p=amg&amp;amp;SQL=\1&lt;/url&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes" noclean="1,2">style=&quot;[^=]*&lt;a href=&quot;[^&quot;]*sql=([^&quot;]*)&quot;&gt;([^&lt;]*)&lt;/a&gt;[^-]*[^&gt;]*&gt;([^&lt;]*)&lt;/TD&gt;[^&gt;]*&gt;(&amp;nbsp;)?([^&lt;]*)&lt;/td&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetArtistSearchResults>
+ <GetArtistDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;url cache=&quot;allmusic-artist.html&quot; function=&quot;ParseAMGArtist&quot;&gt;placeholder&lt;/url&gt;" dest="5">
+ <expression />
+ </RegExp>
+ <RegExp input="$$2" conditional="htbthumbs" output="&lt;url function=&quot;GetHTBThumbs&quot; post=&quot;yes&quot;&gt;http://www.htbackdrops.com/search.php?search_terms=all&amp;amp;cat_id=5&amp;amp;search_keywords=\1&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp input="$$2" conditional="htbfanart" output="&lt;url function=&quot;GetHTBFanart&quot; post=&quot;yes&quot;&gt;http://www.htbackdrops.com/search.php?search_terms=all&amp;amp;cat_id=1&amp;amp;search_keywords=\1&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression noclean="1">&lt;TITLE&gt;allmusic[ (]+ ([^&gt;]*) &gt; Overview</expression>
+ </RegExp>
+ <RegExp input="$$9" output="\1" dest="6">
+ <RegExp input="$$8" output="+\1" dest="9">
+ <expression repeat="yes">([^ ]+)</expression>
+ </RegExp>
+ <expression>\+(.*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;LastfmLink&quot;&gt;http://ws.audioscrobbler.com/2.0/?method=artist.search&amp;amp;artist=$$6&amp;amp;api_key=71e468a84c1f40d4991ddccc46e40f1b&lt;/url&gt;" dest="5+">
+ <expression noclean="1"></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetAMGDiscography&quot;&gt;http://www.allmusic.com/cg/amg.dll?p=amg&amp;amp;sql=\1&lt;/url&gt;" dest="5+">
+ <expression noclean="1">sql=([^&quot;]*)&quot;&gt;Discography</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetArtistDetails>
+ <LastfmLink dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;url function=&quot;GetBiography&quot;&gt;http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&amp;amp;mbid=\2&amp;amp;lang=pl&amp;amp;api_key=71e468a84c1f40d4991ddccc46e40f1b&lt;/url&gt;" dest="2">
+ <expression noclean="1">&lt;artist&gt;.*?&lt;name&gt;([^&lt;]*)&lt;/name&gt;.*?&lt;mbid&gt;([^&lt;]*)&lt;/mbid&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </LastfmLink>
+ <GetBiography dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;biography&gt;\1&lt;/biography&gt;" dest="2">
+ <expression clear="yes">&lt;content&gt;&lt;!\[CDATA\[(.*?)\]</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetBiography>
+</scraper>
diff --git a/system/scrapers/music/common/allmusic.xml b/system/scrapers/music/common/allmusic.xml
new file mode 100644
index 0000000000..89994e4253
--- /dev/null
+++ b/system/scrapers/music/common/allmusic.xml
@@ -0,0 +1,141 @@
+<scraperfunctions>
+ <GetAMGDiscography dest="5">
+ <RegExp input="$$2$$3" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;album&gt;&lt;year&gt;\1&lt;/year&gt;&lt;title&gt;\3&lt;/title&gt;&lt;label&gt;\4&lt;/label&gt;&lt;/album&gt;" dest="2">
+ <expression repeat="yes" clear="yes" noclean="1,3,4">sorted-cell&quot;&gt;([0-9]+)&lt;/td&gt;&lt;td[^&gt;]*&gt;(&lt;a href=[^&gt;]*&gt;&lt;img [^&gt;]*/&gt;&lt;/a&gt;|[^&lt;]*)?&lt;/td&gt;&lt;td[^&gt;]*&gt;&lt;a href=[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;&lt;/td&gt;&lt;td[^&lt;]*&lt;/td&gt;&lt;td[^&gt;]*&gt;([^&lt;]+)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$2" output="\1&amp;amp;\2" dest="3">
+ <expression noclean="1,2" repeat="yes">(.*?)&amp;(.+)</expression>
+ </RegExp>
+ <RegExp input="$$3" output="" dest="2">
+ <expression>(.+)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetAMGDiscography>
+ <GetAMGBiography dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;biography&gt;\1&lt;/biography&gt;" dest="2">
+ <expression clear="yes">Biography&lt;/td&gt;.*?&lt;p&gt;(.*?)&lt;/p&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetAMGBiography>
+ <GetAMGReview dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;review&gt;\1&lt;/review&gt;" dest="2">
+ <expression>Review&lt;/td&gt;.*?&lt;p&gt;(.*?)&lt;/p&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetAMGReview>
+ <ParseAMGArtist dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;name&gt;\1&lt;/name&gt;" dest="5">
+ <expression noclean="1">&lt;TITLE&gt;allmusic[ (]+ ([^&gt;]*) &gt; Overview</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;born&gt;\1&lt;/born&gt;" dest="5+">
+ <expression>&lt;span&gt;Born.*?;&quot;&gt;(.*?)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;died&gt;\1&lt;/died&gt;" dest="5+">
+ <expression>&lt;span&gt;Died.*?;&quot;&gt;(.*?)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;formed&gt;\1&lt;/formed&gt;" dest="5+">
+ <expression>&lt;span&gt;Formed.*?;&quot;&gt;(.*?)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;disbanded&gt;\1&lt;/disbanded&gt;" dest="5+">
+ <expression>&lt;span&gt;Disbanded.*?;&quot;&gt;(.*?)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;yearsactive&gt;\1&lt;/yearsactive&gt;" dest="5+">
+ <expression>&lt;span&gt;Years Active.*?sub&quot;&gt;(.*?)&lt;/div&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">Genre Listing--&gt;([^!]*)&lt;!--Genre Listing</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression noclean="1" repeat="yes">&lt;li&gt;[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">Style Listing--&gt;([^!]*)&lt;!--Style Listing</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;style&gt;\1&lt;/style&gt;" dest="5+">
+ <expression noclean="1" repeat="yes">&lt;li&gt;[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression noclean="1">Moods Listing--&gt;([^!]*)&lt;!--Moods Listing</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;mood&gt;\1&lt;/mood&gt;" dest="5+">
+ <expression noclean="1" repeat="yes">&lt;li&gt;[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">Instruments Listing--&gt;([^!]*)&lt;!--Instruments Listing</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;instruments&gt;\1&lt;/instruments&gt;" dest="5+">
+ <expression noclean="1" repeat="yes">&lt;li&gt;[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="5+">
+ <expression noclean="1">&lt;img src=&quot;([^&quot;]*)&quot; id=&quot;Picture&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;http://image.allmusic.com/00/amg/pic200/dr\1\200/\1\2\3\4/\1\2\3\4\5.jpg&lt;/thumb&gt;" dest="5+">
+ <expression noclean="1" repeat="yes">&quot;([A-Z^])([0-9^])([0-9^])([0-9^])([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </ParseAMGArtist>
+ <ParseAMGAlbum dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression noclean="1">&lt;TITLE&gt;allmusic[ (]+ ([^&gt;]*) &gt; Overview</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;artist&gt;\1&lt;/artist&gt;" dest="5+">
+ <expression noclean="1">&lt;span&gt;Artist&lt;/span&gt;[^;]*[^&gt;]*&gt;[^&gt;]*&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="5+">
+ <expression noclean="1">&lt;span&gt;Rating&lt;/span&gt;[^_]*_r([0-9^]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;label&gt;\1&lt;/label&gt;" dest="5+">
+ <expression noclean="1">&lt;span&gt;Label&lt;/span&gt;[^;]*[^&gt;]*&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;type&gt;\1&lt;/type&gt;" dest="5+">
+ <expression noclean="1">&lt;span&gt;Type&lt;/span&gt;[^;]*[^&gt;]*&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;releasedate&gt;\1&lt;/releasedate&gt;" dest="5+">
+ <expression noclean="1">&lt;span&gt;Release Date&lt;/span&gt;[^;]*[^&gt;]*&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression noclean="1">&lt;span&gt;Release Date.*?([0-9]+)&lt;/</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">Genre[s]* Listing--&gt;([^!]*)&lt;!--Genre[s]* Listing</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression noclean="1" repeat="yes">&lt;li&gt;[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">Style[s]* Listing--&gt;([^!]*)&lt;!--Style[s]* Listing</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;style&gt;\1&lt;/style&gt;" dest="5+">
+ <expression noclean="1" repeat="yes">&lt;li&gt;[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression noclean="1">Mood[s]* Listing--&gt;([^!]*)&lt;!--Mood[s]* Listing</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;mood&gt;\1&lt;/mood&gt;" dest="5+">
+ <expression noclean="1" repeat="yes">&lt;li&gt;[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">Theme[s]* Listing--&gt;([^!]*)&lt;!--Theme[s]* Listing</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;theme&gt;\1&lt;/theme&gt;" dest="5+">
+ <expression noclean="1" repeat="yes">&lt;li&gt;[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;track&gt;&lt;position&gt;\1&lt;/position&gt;&lt;title&gt;\3&lt;/title&gt;&lt;duration&gt;\4&lt;/duration&gt;&lt;/track&gt;" dest="5+">
+ <expression noclean="1,2,3" repeat="yes">&quot;cell&quot;&gt;([0-9]+)&lt;/.*?sql=([0-9:a-z]*)&quot;&gt;(.*?)&lt;/a&gt;.*?&quot;right&quot;.*?&gt;(.*?)&lt;/</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;http://image.allmusic.com/\1&lt;/thumb&gt;" dest="5+">
+ <expression noclean="1">http://image.allmusic.com/([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </ParseAMGAlbum>
+</scraperfunctions>
diff --git a/system/scrapers/music/common/htbackdrops.xml b/system/scrapers/music/common/htbackdrops.xml
new file mode 100644
index 0000000000..9872e4717f
--- /dev/null
+++ b/system/scrapers/music/common/htbackdrops.xml
@@ -0,0 +1,18 @@
+<scraperfunctions>
+ <GetHTBThumbs dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb preview=&quot;http://www.htbackdrops.com/data/thumbnails/\2&quot;&gt;http://www.htbackdrops.com/data/media/\2&lt;/thumb&gt;" dest="13">
+ <expression noclean="1" repeat="yes">mode=search(&amp;amp;sessionid=[^&quot;]*)?&quot;&gt;&lt;img src=&quot;./data/thumbnails/([^&quot;]+)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetHTBThumbs>
+ <GetHTBFanart dest="5">
+ <RegExp input="$$13" output="&lt;details&gt;&lt;fanart url=&quot;http://www.htbackdrops.com/&quot;&gt;\1&lt;/fanart&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb preview=&quot;data/thumbnails/\2&quot;&gt;data/media/\2&lt;/thumb&gt;" dest="13">
+ <expression noclean="1" repeat="yes">mode=search(&amp;amp;sessionid=[^&quot;]*)?&quot;&gt;&lt;img src=&quot;./data/thumbnails/([^&quot;]+)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetHTBFanart>
+</scraperfunctions>
diff --git a/system/scrapers/music/common/lastfm.xml b/system/scrapers/music/common/lastfm.xml
new file mode 100644
index 0000000000..307c9a9c45
--- /dev/null
+++ b/system/scrapers/music/common/lastfm.xml
@@ -0,0 +1,10 @@
+<scraperfunctions>
+ <GetLastFMDiscography dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;album&gt;&lt;title&gt;\1&lt;/title&gt;&lt;/album&gt;" dest="2+">
+ <expression repeat="yes">&lt;album[^&gt;]*&gt;[^&lt;]*&lt;name&gt;([^&lt;]*?)&lt;/name&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetLastFMDiscography>
+</scraperfunctions>
diff --git a/system/scrapers/music/discogs.gif b/system/scrapers/music/discogs.gif
new file mode 100644
index 0000000000..2aba929794
--- /dev/null
+++ b/system/scrapers/music/discogs.gif
Binary files differ
diff --git a/system/scrapers/music/discogs.xml b/system/scrapers/music/discogs.xml
new file mode 100644
index 0000000000..d727e9fa93
--- /dev/null
+++ b/system/scrapers/music/discogs.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.1" date="2009-09-16" name="Discogs" content="albums" thumb="discogs.gif" language="en">
+ <include>common/htbackdrops.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Fanart&quot; type=&quot;bool&quot; id=&quot;htbfanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Grab thumbs from HTBackdrops&quot; type=&quot;bool&quot; id=&quot;htbthumbs&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="\1" dest="3">
+ <expression>(http://www.discogs.com/.*)</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateAlbumSearchUrl dest="3">
+ <RegExp input="$$1" output="http://www.discogs.com/advanced_search?artist=$$2&amp;release_title=\1&amp;btn=Search+Releases" dest="3">
+ <expression/>
+ </RegExp>
+ </CreateAlbumSearchUrl>
+ <GetAlbumSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;artist&gt;\2&lt;/artist&gt;&lt;title&gt;\3&lt;/title&gt;&lt;url&gt;http://www.discogs.com\1&lt;/url&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes">&lt;a href=&quot;([^&quot;]*/release/[^&quot;]*)&quot;.*?&gt;(.*?) - (.*?)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetAlbumSearchResults>
+ <GetAlbumDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;artist&gt;\1&lt;/artist&gt;" dest="5">
+ <expression noclean="1">&lt;a href=&quot;/artist/[^&quot;]+&quot;&gt;(.*?)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5+">
+ <expression noclean="1">Add .*? - (.*?) to your collection</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="5+">
+ <expression noclean="1">Rating:&lt;/td&gt;.*?&lt;b&gt;([0-9]+).[0-9]&lt;/b&gt;/[0-9]+</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;label&gt;\1&lt;/label&gt;" dest="5+">
+ <expression noclean="1">Label:&lt;/td&gt;.*?&gt;([^&lt;]+)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;releasedate&gt;\1&lt;/releasedate&gt;" dest="5+">
+ <expression noclean="1">Released:.*?&lt;td&gt;(.*?)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression noclean="1">Released:.*?&lt;td&gt;.*?([0-9]+)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression trim="1">Genre:&lt;/td&gt;&lt;td&gt;(.*?)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes">([^,]+),?</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression trim="1">Style:&lt;/td&gt;&lt;td&gt;(.*?)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;style&gt;\1&lt;/style&gt;" dest="5+">
+ <expression repeat="yes">([^,]+),?</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">Tracklisting:(.*?)&lt;/table&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;track&gt;&lt;position&gt;\1&lt;/position&gt;&lt;title&gt;\2&lt;/title&gt;&lt;duration&gt;\3&lt;/duration&gt;&lt;/track&gt;" dest="5+">
+ <expression repeat="yes">&quot;left&quot;&gt;[^&lt;0-9]*([0-9]+)&lt;/td&gt;[^:]*&lt;td&gt;([^&lt;]+) \(([:0-9]+)\)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;review&gt;\1&lt;/review&gt;" dest="5+">
+ <expression>User Reviews:&lt;/b&gt;[^&lt;]*&lt;blockquote&gt;[^&lt;]*(&lt;div id=.+?)&lt;div id=</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetImages&quot;&gt;http://www.discogs.com\1&lt;/url&gt;" dest="5+">
+ <expression>&lt;a href=&quot;(/viewimages\?release=[^&quot;]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetAlbumDetails>
+ <GetImages dest="5">
+ <RegExp input="$$4" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="4+">
+ <expression noclean="1" repeat="yes">img src=&quot;(http://www.discogs.com/image/[^&quot;]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetImages>
+ <CreateArtistSearchUrl dest="3">
+ <RegExp input="$$2" output="http://www.discogs.com/search?type=artists&amp;q=&quot;\1&quot;&amp;btn=Search" dest="3">
+ <RegExp input="$$2" output="\1,%20The" dest="2">
+ <RegExp input="$$1" output="\1" dest="2">
+ <expression noclean="1"/>
+ </RegExp>
+ <expression noclean="1" clear="no" repeat="no" trim="1">[Tt]he%20(.+)</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </CreateArtistSearchUrl>
+ <GetArtistSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url&gt;http://www.discogs.com/artist/\1&lt;/url&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes">&lt;a href=&quot;/artist/([^&quot;]*)&quot; class=&quot;rollover_link&quot;&gt;(.+?)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetArtistSearchResults>
+ <GetArtistDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;name&gt;\1&lt;/name&gt;" dest="5">
+ <expression noclean="1">Manage your (.*?) collection</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;biography&gt;\1&lt;/biography&gt;" dest="5+">
+ <expression>Profile:(.*?)URLs:</expression>
+ </RegExp>
+ <RegExp input="$$2" conditional="htbthumbs" output="&lt;url function=&quot;GetHTBThumbs&quot; post=&quot;yes&quot;&gt;http://www.htbackdrops.com/search.php?search_terms=all&amp;amp;cat_id=5&amp;amp;search_keywords=\1&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetImages&quot;&gt;http://www.discogs.com\1&lt;/url&gt;" dest="5+">
+ <expression>a href=&quot;(/viewimages\?artist=[^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$2" conditional="htbfanart" output="&lt;url function=&quot;GetHTBFanart&quot; post=&quot;yes&quot;&gt;http://www.htbackdrops.com/search.php?search_terms=all&amp;amp;cat_id=1&amp;amp;search_keywords=\1&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetArtistDetails>
+</scraper>
diff --git a/system/scrapers/music/freebase.png b/system/scrapers/music/freebase.png
new file mode 100644
index 0000000000..7b14e32b7b
--- /dev/null
+++ b/system/scrapers/music/freebase.png
Binary files differ
diff --git a/system/scrapers/music/freebase.xml b/system/scrapers/music/freebase.xml
new file mode 100644
index 0000000000..4399e47a5a
--- /dev/null
+++ b/system/scrapers/music/freebase.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.1" date="2009-09-16" name="Freebase" content="albums" thumb="freebase.png">
+ <include>common/htbackdrops.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Fanart&quot; type=&quot;bool&quot; id=&quot;htbfanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Grab thumbs from HTBackdrops&quot; type=&quot;bool&quot; id=&quot;htbthumbs&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://api.freebase.com/api/service/mqlread?query={%22query%22:{%22type%22:%22/music/artist%22,%22name%22:null,%22genre%22:[],%22album%22:[{%22id%22:%22/\2%22,%22/common/topic/article%22:[{%22guid%22:null,%22optional%22:true,%22limit%22:1}],%22/common/topic/image%22:[{%22guid%22:null,%22optional%22:true,%22limit%22:1}],%22label%22:[],%22engineer%22:[],%22producer%22:[],%22release_type%22:null,%22artist%22:null,%22name%22:null,%22release_date%22:null,%22track%22:[{%22name%22:null,%22length%22:null,%22index%22:null,%22sort%22:%22index%22,%22optional%22:true}],%22sort%22:%22release_date%22}]}}&lt;/url&gt;" dest="3+">
+ <expression>(http://www.freebase.com/view/)(.*)</expression>
+ </RegExp>
+ </NfoUrl>
+
+ <CreateAlbumSearchUrl dest="3">
+ <RegExp input="$$1" output="http://api.freebase.com/api/service/mqlread?query={%22query%22:{%22type%22:%22/music/artist%22,%22name~=%22:%22$$2%22,%22album%22:[{%22guid%22:null,%22artist%22:null,%22name%22:null,%22name~=%22:%22\1%22}]}}" dest="3">
+ <expression/>
+ </RegExp>
+ </CreateAlbumSearchUrl>
+
+ <GetAlbumSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;artist&gt;\1&lt;/artist&gt;&lt;title&gt;\3&lt;/title&gt;&lt;url&gt;http://api.freebase.com/api/service/mqlread?query={%22query%22:{%22type%22:%22/music/artist%22,%22name%22:null,%22genre%22:[],%22album%22:[{%22id%22:%22/guid/\2%22,%22/common/topic/article%22:[{%22guid%22:null,%22optional%22:true,%22limit%22:1}],%22/common/topic/image%22:[{%22guid%22:null,%22optional%22:true,%22limit%22:1}],%22label%22:[],%22engineer%22:[],%22producer%22:[],%22release_type%22:null,%22artist%22:null,%22name%22:null,%22release_date%22:null,%22track%22:[{%22name%22:null,%22length%22:null,%22index%22:null,%22sort%22:%22index%22,%22optional%22:true}],%22sort%22:%22release_date%22}]}}&lt;/url&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes">&quot;artist&quot;: &quot;([^&quot;]*)&quot;.*?&quot;guid&quot;: &quot;#([^&quot;]*)&quot;.*?&quot;name&quot;: &quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetAlbumSearchResults>
+
+ <GetAlbumDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;artist&gt;\1&lt;/artist&gt;" dest="5">
+ <expression noclean="1">&quot;artist&quot;: &quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5+">
+ <expression noclean="1">&quot;name&quot;: &quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression trim="1">&quot;label&quot;: (.*?)\]</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;label&gt;\1&lt;/label&gt;" dest="5+">
+ <expression noclean="1" repeat="yes">&quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;type&gt;\1&lt;/type&gt;" dest="5+">
+ <expression noclean="1">&quot;release_type&quot;: &quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;releasedate&gt;\1&lt;/releasedate&gt;" dest="5+">
+ <expression noclean="1">&quot;release_date&quot;: &quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression noclean="1">&quot;release_date&quot;: &quot;([0-9]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6+">
+ <expression trim="1">&quot;genre&quot;: (.*?)\]</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression noclean="1" repeat="yes">&quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;track&gt;&lt;position&gt;\1&lt;/position&gt;&lt;title&gt;\3&lt;/title&gt;&lt;duration&gt;\2&lt;/duration&gt;&lt;/track&gt;" dest="5+">
+ <expression repeat="yes">&quot;index&quot;: ([0-9]+).*?&quot;length&quot;: ([0-9]+).*?&quot;name&quot;: &quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;http://www.freebase.com/api/trans/raw/guid/\1&lt;/thumb&gt;" dest="5+">
+ <expression noclean="1">image&quot;:.*?&quot;guid&quot;: &quot;#([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetAlbumReview&quot;&gt;http://www.freebase.com/api/trans/raw/guid/\1&lt;/url&gt;" dest="5+">
+ <expression noclean="1">article&quot;:.*?&quot;guid&quot;: &quot;#([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetAlbumDetails>
+
+ <GetAlbumReview dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;review&gt;\1&lt;/review&gt;" dest="2">
+ <expression noclean="1">&lt;p&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetAlbumReview>
+
+ <CreateArtistSearchUrl dest="3">
+ <RegExp input="$$1" output="http://www.freebase.com/api/service/search?query=\1&type=/music/artist&indent=1" dest="3">
+ <expression/>
+ </RegExp>
+ </CreateArtistSearchUrl>
+
+ <GetArtistSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url&gt;http://api.freebase.com/api/service/mqlread?query={%22query%22:{%22type%22:%22/music/artist%22,%22id%22:%22/guid/\1%22,%22/common/topic/article%22:[{%22guid%22:null,%22optional%22:true,%22limit%22:1}],%22/common/topic/image%22:[{%22guid%22:null,%22optional%22:true,%22limit%22:1}],%22name%22:null,%22genre%22:[],%22album%22:[],%22active_start%22:null,%22active_end%22:null,%22instruments_played%22:[]}}&lt;/url&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes">&quot;guid&quot;: &quot;#([^&quot;]*)&quot;.*?&quot;name&quot;: &quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetArtistSearchResults>
+
+ <GetArtistDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;name&gt;\1&lt;/name&gt;" dest="5">
+ <expression noclean="1">&quot;name&quot;: &quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;formed&gt;\1&lt;/formed&gt;" dest="5+">
+ <expression noclean="1">&quot;active_start&quot;: &quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;disbanded&gt;\1&lt;/disbanded&gt;" dest="5+">
+ <expression noclean="1">&quot;active_end&quot;: &quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression trim="1">&quot;genre&quot;: (.*?)\]</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes">&quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression trim="1">&quot;album&quot;: (.*?)\]</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;album&gt;&lt;title&gt;\1&lt;/title&gt;&lt;/album&gt;" dest="5+">
+ <expression noclean="1" repeat="yes">&quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;http://www.freebase.com/api/trans/raw/guid/\1&lt;/thumb&gt;" dest="5+">
+ <expression noclean="1">image&quot;:.*?&quot;guid&quot;: &quot;#([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$2" conditional="htbthumbs" output="&lt;url function=&quot;GetHTBThumbs&quot; post=&quot;yes&quot;&gt;http://www.htbackdrops.com/search.php?search_terms=all&amp;amp;cat_id=5&amp;amp;search_keywords=\1&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp input="$$2" conditional="htbfanart" output="&lt;url function=&quot;GetHTBFanart&quot; post=&quot;yes&quot;&gt;http://www.htbackdrops.com/search.php?search_terms=all&amp;amp;cat_id=1&amp;amp;search_keywords=\1&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetBiography&quot;&gt;http://www.freebase.com/api/trans/raw/guid/\1&lt;/url&gt;" dest="5+">
+ <expression noclean="1">article&quot;:.*?&quot;guid&quot;: &quot;#([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetArtistDetails>
+
+ <GetBiography dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;biography&gt;\1&lt;/biography&gt;" dest="2">
+ <expression noclean="1">&lt;p&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetBiography>
+</scraper>
diff --git a/system/scrapers/music/israel-music.png b/system/scrapers/music/israel-music.png
new file mode 100644
index 0000000000..932c3abf75
--- /dev/null
+++ b/system/scrapers/music/israel-music.png
Binary files differ
diff --git a/system/scrapers/music/israel-music.xml b/system/scrapers/music/israel-music.xml
new file mode 100644
index 0000000000..62010304ee
--- /dev/null
+++ b/system/scrapers/music/israel-music.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.0" date="2009-05-22" name="IsraelMusic" content="albums" thumb="israel-music.png">
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="\1/" dest="3">
+ <expression>(http://he.israel-music.com.*)</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateAlbumSearchUrl dest="3">
+ <RegExp input="$$1" output='http://he.israel-music.com/search/\1/' dest="3">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$2%20$$1" output='http://he.israel-music.com/search/\1/' dest="3">
+ <expression></expression>
+ </RegExp>
+ </CreateAlbumSearchUrl>
+ <GetAlbumSearchResults dest="8">
+ <RegExp input="$$5" output='&lt;?xml version="1.0" encoding="utf-8" standalone="yes"?&gt;&lt;results&gt;\1&lt;/results&gt;' dest="8">
+ <RegExp input="$$1" output='&lt;entity&gt;&lt;url&gt;http://he.israel-music.com\1&lt;/url&gt;&lt;title&gt;\2&lt;/title&gt;&lt;/entity&gt;' dest="5+">
+ <expression repeat="yes" noclean='1,2'><![CDATA[<strong><a dir="rtl" href="(.[^"]*)">(.[^<]*)</a>]]></expression>
+ </RegExp>
+ <RegExp input="$$1" output='&lt;entity&gt;&lt;url&gt;http://he.israel-music.com\1&lt;/url&gt;&lt;title&gt;\2&lt;/title&gt;&lt;artist&gt;\4&lt;/artist&gt;&lt;year&gt;\5&lt;/year&gt;&lt;/entity&gt;' dest="5+">
+ <expression repeat="yes" noclean='1,3,4,5'><![CDATA[<strong><a dir="rtl" href="(.[^"]*)">(.*?)</a> - <a dir="rtl" href="(.[^"]*)">(.[^<]*)</a> <span>([0-9]*)</span></strong>]]></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetAlbumSearchResults>
+ <GetAlbumDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression noclean="1"><![CDATA[<h1>(.[^<]*)</h1>]]></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;artist&gt;\1&lt;/artist&gt;" dest="5+">
+ <expression noclean="1"><![CDATA[</span><a.[^>]*>(.[^<]*)</a>]]></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;review&gt;\1&lt;/review&gt;" dest="5+">
+ <expression><![CDATA[<ul id="details".[^>]*>(.*)</ul>.[^<]*<p style="clear:both">]]></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="5+">
+ <expression noclean="1"><![CDATA[id="imagef" src="(.[^"]*)"]]></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression noclean="1"><![CDATA[<li><b>Ч©Ч Ч”: </b> ([0-9]+)</li>]]></expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1"><![CDATA[<li><b>Ч–'ЧђЧ ЧЁ:</b>(.*)</li>]]></expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression noclean="1" repeat="yes"><![CDATA[<a.[^>]*">(.[^<]*)</a>]]></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetAlbumDetails>
+</scraper>
diff --git a/system/scrapers/music/lastfm.xml b/system/scrapers/music/lastfm.xml
new file mode 100644
index 0000000000..494b3a5b58
--- /dev/null
+++ b/system/scrapers/music/lastfm.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.1" date="2009-09-16" name="Last.FM" content="albums" thumb="lastfm.gif">
+ <include>common/htbackdrops.xml</include>
+ <include>common/lastfm.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Fanart&quot; type=&quot;bool&quot; id=&quot;htbfanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Grab thumbs from HTBackdrops&quot; type=&quot;bool&quot; id=&quot;htbthumbs&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="http://ws.audioscrobbler.com/2.0/?method=album.getinfo&amp;album=\2&amp;artist=\1&amp;api_key=71e468a84c1f40d4991ddccc46e40f1b" dest="3">
+ <expression>(http://www.last.fm/music/([^/]*)/(.*))</expression>
+ </RegExp>
+ <RegExp input="$$1" output="http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&amp;artist=\1&amp;api_key=71e468a84c1f40d4991ddccc46e40f1b" dest="3">
+ <expression>(http://www.last.fm/music/([^/]*))$</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateAlbumSearchUrl dest="3">
+ <RegExp input="$$1" output="http://ws.audioscrobbler.com/2.0/?method=album.search&amp;album=\1&amp;artist=$$2&amp;api_key=71e468a84c1f40d4991ddccc46e40f1b" dest="3">
+ <expression/>
+ </RegExp>
+ </CreateAlbumSearchUrl>
+ <GetAlbumSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;artist&gt;\2&lt;/artist&gt;&lt;title&gt;\1&lt;/title&gt;&lt;url&gt;http://ws.audioscrobbler.com/2.0/?method=album.getinfo&amp;amp;album=\4&amp;amp;artist=\3&amp;amp;api_key=71e468a84c1f40d4991ddccc46e40f1b&lt;/url&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes">&lt;album&gt;.*?&lt;name&gt;([^&lt;]*)&lt;/name&gt;.*?&lt;artist&gt;([^&lt;]*)&lt;/artist&gt;.*?&lt;url&gt;http://www.last.fm/music/([^/]+)/(.*?)&lt;/url&gt;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetAlbumSearchResults>
+ <GetAlbumDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;artist&gt;\1&lt;/artist&gt;" dest="5">
+ <expression noclean="1">&lt;artist&gt;(.*?)&lt;/artist&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5+">
+ <expression noclean="1">&lt;name&gt;(.*?)&lt;/name&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;releasedate&gt;\1&lt;/releasedate&gt;" dest="5+">
+ <expression trim="1">&lt;releasedate&gt;:(.*?)&lt;/releasedate&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression trim="1">&lt;releasedate&gt;[^,]*([0-9]+),&lt;/releasedate&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;review&gt;\1&lt;/review&gt;" dest="5+">
+ <expression>&lt;content&gt;&lt;!\[CDATA\[(.*)\]\]&gt;&lt;/content&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;\2&lt;/thumb&gt;" dest="5+">
+ <expression noclean="1">&lt;image size=&quot;(extra)?large&quot;&gt;([^&lt;]*)&lt;/image&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetTracks&quot;&gt;http://ws.audioscrobbler.com/2.0/?method=playlist.fetch&amp;amp;playlistURL=lastfm://playlist/album/\1&amp;amp;api_key=71e468a84c1f40d4991ddccc46e40f1b&lt;/url&gt;" dest="5+">
+ <expression noclean="1">&lt;id&gt;(.*?)&lt;/id&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetAlbumDetails>
+ <GetTracks dest="5">
+ <RegExp input="$$4" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;track&gt;&lt;title&gt;\1&lt;/title&gt;&lt;/track&gt;" dest="4+">
+ <expression noclean="1" repeat="yes">&lt;track&gt;.*?&lt;title&gt;(.*?)&lt;/title&gt;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetTracks>
+ <CreateArtistSearchUrl dest="3">
+ <RegExp input="$$1" output="http://ws.audioscrobbler.com/2.0/?method=artist.search&amp;artist=\1&amp;api_key=71e468a84c1f40d4991ddccc46e40f1b" dest="3">
+ <expression/>
+ </RegExp>
+ </CreateArtistSearchUrl>
+ <GetArtistSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\1&lt;/title&gt;&lt;url&gt;http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&amp;amp;mbid=\2&amp;amp;api_key=71e468a84c1f40d4991ddccc46e40f1b&lt;/url&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes">&lt;artist&gt;.*?&lt;name&gt;([^&lt;]*)&lt;/name&gt;.*?&lt;mbid&gt;([^&lt;]*)&lt;/mbid&gt;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetArtistSearchResults>
+ <GetArtistDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;name&gt;\1&lt;/name&gt;" dest="5">
+ <expression noclean="1">&lt;name&gt;([^&lt;]*)&lt;/name&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;biography&gt;\1&lt;/biography&gt;" dest="5+">
+ <expression>&lt;content&gt;&lt;!\[CDATA\[(.*?)\]</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;\2&lt;/thumb&gt;" dest="5+">
+ <expression noclean="1">&lt;image size=&quot;(extra)?large&quot;&gt;([^&lt;]*)&lt;/image&gt;</expression>
+ </RegExp>
+ <RegExp input="$$2" conditional="htbthumbs" output="&lt;url function=&quot;GetHTBThumbs&quot; post=&quot;yes&quot;&gt;http://www.htbackdrops.com/search.php?search_terms=all&amp;amp;cat_id=5&amp;amp;search_keywords=\1&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp input="$$2" conditional="htbfanart" output="&lt;url function=&quot;GetHTBFanart&quot; post=&quot;yes&quot;&gt;http://www.htbackdrops.com/search.php?search_terms=all&amp;amp;cat_id=1&amp;amp;search_keywords=\1&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetGenres&quot;&gt;http://ws.audioscrobbler.com/2.0/?method=artist.gettoptags&amp;amp;artist=\1&amp;amp;api_key=71e468a84c1f40d4991ddccc46e40f1b&lt;/url&gt;" dest="5+">
+ <expression noclean="1">&lt;url&gt;http://www.last.fm/music/(.*?)&lt;/url&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetLastFMDiscography&quot;&gt;http://ws.audioscrobbler.com/2.0/?method=artist.gettopalbums&amp;amp;artist=\1&amp;amp;api_key=71e468a84c1f40d4991ddccc46e40f1b&lt;/url&gt;" dest="5+">
+ <expression noclean="1">&lt;url&gt;http://www.last.fm/music/(.*?)&lt;/url&gt;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetArtistDetails>
+ <GetGenres dest="5">
+ <RegExp input="$$4" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="4">
+ <expression noclean="1">&lt;tag&gt;.*?&lt;name&gt;([^/lt;]*)&lt;/name&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;style&gt;\1&lt;/style&gt;" dest="4+">
+ <expression repeat="yes" noclean="1">&lt;tag&gt;.*?&lt;name&gt;([^/lt;]*)&lt;/name&gt;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetGenres>
+</scraper>
diff --git a/system/scrapers/video/AdultFilmdatabase.gif b/system/scrapers/video/AdultFilmdatabase.gif
new file mode 100644
index 0000000000..1b9203dca8
--- /dev/null
+++ b/system/scrapers/video/AdultFilmdatabase.gif
Binary files differ
diff --git a/system/scrapers/video/Excalibur.jpg b/system/scrapers/video/Excalibur.jpg
new file mode 100644
index 0000000000..95a5e25dc1
--- /dev/null
+++ b/system/scrapers/video/Excalibur.jpg
Binary files differ
diff --git a/system/scrapers/video/Excalibur.xml b/system/scrapers/video/Excalibur.xml
new file mode 100644
index 0000000000..da94649863
--- /dev/null
+++ b/system/scrapers/video/Excalibur.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<scraper framework="1.1" date="2009-08-05" name="Excalibur" content="movies" thumb="excalibur.jpg" language="en">
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.excaliburfilms.com/AdultDVD/\1.htm&lt;/url&gt;" dest="3">
+ <expression noclean="1">excaliburfilms.com/AdultDVD/([^.]*)</expression>
+ </RegExp>
+ </NfoUrl>
+
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://search.excaliburfilms.com/excals.htm?searchString=\1&amp;amp;Search=AdultDVDMovies&amp;amp;SearchFor=Title.x&lt;/url&gt;" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+
+ <GetSearchResults dest="6">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="6">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url&gt;http://www.excaliburfilms.com/AdultDVD/\1&lt;/url&gt;&lt;/entity&gt;" dest="5+">
+ <expression trim="1" repeat="yes">&lt;a href=&quot;http://www.ExcaliburFilms.com/AdultDVD/([^&quot;]*)&quot;.*?&lt;font class=&quot;searchTitle13&quot;&gt;([^&lt;]*)&lt;/font&gt;&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;thumb&gt;http://images.excaliburfilms.com/DVD/reviews/imagesBB020609/largemoviepic/\1.jpg&lt;/thumb&gt;" dest="5+">
+ <expression>imagesBB020609/([^\.]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;http://images.excaliburfilms.com/DVD/reviews/imagesBB020609/largemoviepic/\1-b.jpg&lt;/thumb&gt;" dest="5+">
+ <expression>imagesBB020609/([^\.]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5+">
+ <expression>Rent ([^D]*) </expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;actor&gt;&lt;name&gt;\3&lt;/name&gt;&lt;thumb&gt;http://images.excaliburfilms.com/pornlist/starpicsAA020309/\2.jpg&lt;/thumb&gt;&lt;/actor&gt;" dest="5+">
+ <expression repeat="yes">&lt;a href=&quot;/pornlist/(starpgs|malepgs)/([^\.]*)[^&gt;]*&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression>href=&apos;/DVD/[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;&lt;BR&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>/excal/release[^&gt;]*&gt;[0-9]*/[0-9]*/([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;runtime&gt;\1 mins&lt;/runtime&gt;" dest="5+">
+ <expression>Time: &lt;/font&gt;&lt;[^&gt;]*&gt;([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>Description:&lt;/font&gt;&lt;/a&gt;[^&gt;]*&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="5+">
+ <expression>href=&apos;/dvd/adultstudios/[^&gt;]*&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <expression>&gt;Director: &lt;/font&gt;[^&gt;]*&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1.\2&lt;/rating&gt;" dest="5+">
+ <expression>/Stars_([0-9])-([0-9]).gif</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="5+">
+ <expression>/Stars_([0-9]).gif</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+</scraper>
diff --git a/system/scrapers/video/KinoPoisk.gif b/system/scrapers/video/KinoPoisk.gif
new file mode 100644
index 0000000000..dbc35ac38e
--- /dev/null
+++ b/system/scrapers/video/KinoPoisk.gif
Binary files differ
diff --git a/system/scrapers/video/KinoPoisk.xml b/system/scrapers/video/KinoPoisk.xml
new file mode 100644
index 0000000000..7fbef0ce05
--- /dev/null
+++ b/system/scrapers/video/KinoPoisk.xml
@@ -0,0 +1,342 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<scraper framework="1.1" date="2009-08-08" name="KinoPoisk_v2.001.ru" content="movies" thumb="KinoPoisk.gif" ServerContentEncoding="CP1251" language="ru">
+
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;фанарт в виде фото (выбрать одно)&quot; type=&quot;bool&quot; id=&quot;fanartP&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;фанарт в виде обоев (выбрать одно)&quot; type=&quot;bool&quot; id=&quot;fanartR&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;фанарт с сайта (www.themoviedb.org) (выбрать одно)&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;фанарт с сайта (www.themoviedb.org) +24 (выбрать одно)&quot; type=&quot;bool&quot; id=&quot;fanartF&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;трейлер с сайта (www.imdb.com)&quot; type=&quot;bool&quot; id=&quot;trailerI&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="http://www.kinopoisk.ru/index.php?level=7&amp;from=forma&amp;result=adv&amp;m_act%5Bfrom%5D=forma&amp;m_act%5Bwhat%5D=content&amp;m_act%5Bfind%5D=\1&amp;m_act%5Byear%5D=&amp;m_act%5Bcountry%5D=&amp;m_act%5Bgenre%5D=&amp;m_act%5Bcompany%5D=&amp;m_act%5Bmpaa%5D=&amp;m_act%5Bactor%5D=&amp;m_act%5Bcast%5D=&amp;m_act%5Bcontent_find%5D=" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;windows-1251&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+
+ <RegExp input="$$7" output="&lt;entity&gt;\1&lt;/entity&gt;" dest="5+">
+ <RegExp input="$$1" output="$$1" dest="6">
+ <expression clear="yes">img src=&quot;/images/title002.gif&quot;</expression>
+ </RegExp>
+
+ <RegExp input="$$6" output="&lt;title&gt;\1 " dest="7">
+ <expression trim="1">&lt;title&gt;([^&lt;]+)&lt;/title&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="(\1)&lt;/title&gt;" dest="7+">
+ <expression>&lt;tr&gt;&lt;td class=&quot;desc-title&quot; height=25&gt;&lt;img[^&gt;]+&gt;год&lt;/td&gt;&lt;td class=&quot;desc-data&quot;&gt;&lt;a[^&gt;]+&gt;([0-9]+)&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;url&gt;http://www.kinopoisk.ru/level/1/film/\1&lt;/url&gt;" dest="7+">
+ <expression>href=&quot;/level/19/film/([^&quot;]+)&quot; class=&quot;all&quot;&gt;\.\.\.&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2 (\3)&lt;/title&gt;&lt;url&gt;http://www.kinopoisk.ru/level\1&lt;/url&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes">&lt;a class=&quot;all&quot; href="/level([^&quot;]*)&quot;&gt;([^&lt;]*)&lt;/a&gt;,&amp;nbsp;&lt;a[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails clearbuffers="no" dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <!-- TITLE -->
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression trim="1">&lt;title&gt;([^&lt;]+)&lt;/title&gt;</expression>
+ </RegExp>
+ <!-- YEAR -->
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>&lt;tr&gt;&lt;td class=&quot;desc-title&quot; height=25&gt;&lt;img[^&gt;]+&gt;год&lt;/td&gt;&lt;td class=&quot;desc-data&quot;&gt;&lt;a[^&gt;]+&gt;([0-9]+)&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;</expression>
+ </RegExp>
+ <!-- TOP250 -->
+ <RegExp input="$$1" output="&lt;top250&gt;\1&lt;/top250&gt;" dest="5+">
+ <expression>Top250: &lt;a[^&gt;]+&gt;([0-9]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <!-- MPAA -->
+ <RegExp input="$$1" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;" dest="5+">
+ <expression>&lt;tr&gt;&lt;td class=&quot;desc-title&quot; height=25&gt;&lt;img[^&gt;]+&gt;рейтинг MPAA&lt;/td&gt;&lt;td class=&quot;desc-data&quot;.*?&gt;&lt;a href=.+?/rn/(.+?)/</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;certification&gt;\1 \3&lt;/certification&gt;" dest="5+">
+ <expression repeat="yes">&lt;a href=&quot;/List\?certificates=[^&quot;]*&quot;&gt;([^&lt;]*)&lt;/a&gt;[^&lt;]*(&lt;i&gt;([^&lt;]*)&lt;/i&gt;)?</expression>
+ </RegExp>
+ <!-- TAGLINE -->
+ <RegExp input="$$1" output="&lt;tagline&gt;\1&lt;/tagline&gt;" dest="5+">
+ <expression>&lt;tr&gt;&lt;td class=&quot;desc-title&quot; height=25&gt;&lt;img[^&gt;]+&gt;слоган&lt;/td&gt;&lt;td class=&quot;desc-data&quot;&gt;&amp;laquo;([^&lt;]*)&amp;raquo;&lt;/td&gt;&lt;/tr&gt;</expression>
+ </RegExp>
+ <!-- RUNTIME -->
+ <RegExp input="$$1" output="&lt;runtime&gt;\1 min&lt;/runtime&gt;" dest="5+">
+ <expression>&lt;tr&gt;&lt;td class=&quot;desc-title&quot; height=25&gt;&lt;img[^&gt;]+&gt;время&lt;/td&gt;&lt;td class=&quot;desc-data&quot;&gt;([0-9]+) мин&lt;/td&gt;&lt;/tr&gt;</expression>
+ </RegExp>
+ <!-- RATING -->
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;&lt;votes&gt;\2&lt;/votes&gt;" dest="5+">
+ <expression>IMDB: ([0-9.]+) \(([0-9\s]+)\)&lt;/div&gt;</expression>
+ </RegExp>
+ <!-- GENRE -->
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes">genre[^&quot;]*&quot; class=&quot;all&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <!-- STUDIO -->
+ <RegExp input="$$1" output="&lt;url function=&quot;STT&quot;&gt;http://www.kinopoisk.ru\1&lt;/url&gt;" dest="5+">
+ <expression>href=&quot;([^&quot;]+)&quot;&gt;&lt;b&gt;&lt;font color=&quot;#ff6600&quot;&gt;с&lt;/font&gt;&lt;font color=&quot;#555555&quot;&gt;тудии&lt;/font&gt;</expression>
+ </RegExp>
+
+ <!-- DIRECTORS WRITERS ACTORS -->
+ <RegExp input="$$1" output="&lt;url function=&quot;PEOPLE&quot;&gt;http://www.kinopoisk.ru/level/19/film/\1&lt;/url&gt;" dest="5+">
+ <expression>href=&quot;/level/19/film/([^&quot;]+)&quot; class=&quot;all&quot;&gt;\.\.\.&lt;/a&gt;</expression>
+ </RegExp>
+
+ <!-- OUTLINE PLOT -->
+ <RegExp input="$$1" output="\1&amp;#133;&amp;hellip;&amp;laquo;&amp;#151;&amp;mdash;&amp;nbsp;" dest="2">
+ <expression noclean="1">&lt;tr&gt;&lt;td colspan=3 style=&quot;padding:10px;padding-left:20px;&quot; class=&quot;news&quot;&gt;[\t\n]*(.*?)[\t\n]*&lt;/td&gt;&lt;/tr&gt;\s+&lt;tr&gt;&lt;td colspan=3 height=5&gt;&lt;spacer type=block height=5&gt;&lt;/td&gt;&lt;/tr&gt;</expression>
+ </RegExp>
+ <RegExp input="$$4" output="&lt;outline&gt;\1&lt;/outline&gt;&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <RegExp input="$$2" output="\1 " dest="4">
+ <expression repeat="yes">(.*?)&amp;nbsp;</expression>
+ </RegExp>
+ <RegExp input="$$4" output="\1- " dest="4">
+ <expression repeat="yes">(.*?)&amp;mdash;</expression>
+ </RegExp>
+ <RegExp input="$$4" output="\1- " dest="4">
+ <expression repeat="yes">(.*?)&amp;#151;</expression>
+ </RegExp>
+ <RegExp input="$$4" output="\1&quot;" dest="4">
+ <expression repeat="yes">(.*?)&amp;[lr]aquo;</expression>
+ </RegExp>
+ <RegExp input="$$4" output="\1..." dest="4">
+ <expression repeat="yes">(.*?)&amp;hellip;</expression>
+ </RegExp>
+ <RegExp input="$$4" output="\1..." dest="4">
+ <expression repeat="yes">(.*?)&amp;#133;</expression>
+ </RegExp>
+ <expression trim="1">(.*)\.\.\.</expression>
+ </RegExp>
+ <!-- POSTERS -->
+
+ <RegExp input="$$1" output="&lt;url function=&quot;GMP&quot;&gt;http://www.kinopoisk.ru/level/17/film/\1&lt;/url&gt;" dest="5+">
+ <expression>href=&quot;/level/17/film/([^&quot;]+)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url cache=&quot;KinoPoisk_opa.html&quot; function=&quot;GetPoster&quot;&gt;http://www.kinopoisk.ru/&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+
+ <RegExp conditional="fanartP" input="$$1" output="&lt;url function=&quot;GMF&quot;&gt;http://www.kinopoisk.ru/level/13/film/\1&lt;/url&gt;" dest="5+">
+ <expression>href=&quot;/level/13/film/([^&quot;]+)&quot;</expression>
+ </RegExp>
+ <RegExp conditional="fanartR" input="$$1" output="&lt;url function=&quot;GMFR&quot;&gt;http://www.kinopoisk.ru/level/12/film/\1&lt;/url&gt;" dest="5+">
+ <expression>href=&quot;/level/12/film/([^&quot;]+)&quot;</expression>
+ </RegExp>
+
+ <RegExp conditional="fanart" input="$$8" output="&lt;url function=&quot;GMA&quot;&gt;http://themoviedb.org/search?search%5Btext%5D=\1&lt;/url&gt;" dest="5+">
+ <RegExp input="$$1" output="\2" dest="8">
+ <expression>&lt;span style=&quot;font-size:13px;color:#666&quot;&gt;(The )?([^&lt;]+)&lt;/span&gt;</expression>
+ </RegExp>
+ <expression/>
+ </RegExp>
+
+ <RegExp conditional="fanartF" input="$$8" output="&lt;url function=&quot;GMAF&quot;&gt;http://themoviedb.org/search?search%5Btext%5D=\1&lt;/url&gt;" dest="5+">
+ <RegExp input="$$1" output="\2" dest="8">
+ <expression>&lt;span style=&quot;font-size:13px;color:#666&quot;&gt;(The )?([^&lt;]+)&lt;/span&gt;</expression>
+ </RegExp>
+ <expression/>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;url cache=&quot;KinoPoisk_opa.html&quot; function=&quot;GetFanart&quot;&gt;http://www.kinopoisk.ru/&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ </GetDetails>
+
+ <GMTR dest="10">
+ <RegExp input="$$9" output="&lt;details&gt;\1&lt;/details&gt;" dest="10">
+ <RegExp input="$$1" output="&lt;url&gt;http://akas.imdb.com/video/imdb/vi\1/player&lt;/url&gt;" dest="7">
+ <expression noclean="1">&lt;imdb&gt;tt([^&quot;]+)&lt;/imdb&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;url function=&quot;GetTrailer&quot;&gt;\1&lt;/url&gt;" dest="9">
+ <expression noclean="1">&lt;url&gt;([^&lt;]+)&lt;/url&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GMTR>
+
+ <GetTrailer clearbuffers="no" dest="5">
+ <RegExp conditional="trailer" input="$$2" output="&lt;details&gt;&lt;trailer urlencoded=&quot;yes&quot;&gt;\1&lt;/trailer&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="2">
+ <expression noclean="1">&quot;file&quot;[^&quot;]*&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="$$2/\1" dest="2">
+ <expression noclean="1">&quot;id&quot;[^&quot;]*&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetTrailer>
+
+ <GMA dest="10">
+ <RegExp input="$$9" output="&lt;details&gt;\1&lt;/details&gt;" dest="10">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.themoviedb.org/movie/\1/backdrops&lt;/url&gt;" dest="7">
+ <expression noclean="1">&lt;a href=&quot;/movie/([^&quot;]+)&quot;&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;url function=&quot;GMFFS&quot;&gt;\1&lt;/url&gt;" dest="9">
+ <expression noclean="1">&lt;url&gt;([^&lt;]+)&lt;/url&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GMA>
+
+ <GMAF dest="10">
+ <RegExp input="$$9" output="&lt;details&gt;\1&lt;/details&gt;" dest="10">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.themoviedb.org/movie/\1/backdrops&lt;/url&gt;" dest="7">
+ <expression repeat="yes" noclean="1">&lt;a href=&quot;/movie/([^&quot;]+)&quot;&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;url function=&quot;GMFFS&quot;&gt;\1&lt;/url&gt;" dest="9">
+ <expression repeat="yes" noclean="1">&lt;url&gt;([^&lt;]+)&lt;/url&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GMAF>
+
+ <GMFFS dest="10" clearbuffers="no">
+ <RegExp input="$$1" output="&lt;thumb&gt;http://www.themoviedb.org/image/backdrops/\1&lt;/thumb&gt;" dest="6+">
+ <expression repeat="yes" noclean="1">&lt;a href=&quot;/image/backdrops/([^&quot;]+)&quot;</expression>
+ </RegExp>
+ </GMFFS>
+
+ <GMFFSS clearbuffers="no" dest="5">
+ <RegExp input="$$1" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="6+">
+ <expression repeat="yes" noclean="1">&lt;backdrop size=&quot;original&quot;&gt;([^&lt;]+)&lt;/backdrop&gt;</expression>
+ </RegExp>
+ </GMFFSS>
+
+ <GMF dest="10">
+ <RegExp input="$$9" output="&lt;details&gt;\1&lt;/details&gt;" dest="10">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.kinopoisk.ru\1&lt;/url&gt;" dest="7">
+ <expression repeat="yes" noclean="1">&lt;a href=&quot;([^&quot;]+)&quot;&gt;&lt;img[^&gt;]+alt=&quot;Просмотр фото&quot;&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;url function=&quot;GMFF&quot;&gt;\1&lt;/url&gt;" dest="9">
+ <expression repeat="yes" noclean="1">&lt;url&gt;([^&lt;]+)&lt;/url&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GMF>
+
+ <GMFF clearbuffers="no" dest="5">
+ <RegExp input="$$1" output="&lt;thumb&gt;http://www.kinopoisk.ru\1&lt;/thumb&gt;" dest="6+">
+ <expression noclean="1">&lt;img.+?src=&apos;([^&apos;]*kadr[^&apos;]*)&apos;.+?style=&quot;border:1px solid #777&quot; onLoad=&apos;&apos;&gt;&lt;/a&gt;&lt;/td&gt;</expression>
+ </RegExp>
+ </GMFF>
+
+ <GMFR dest="10">
+ <RegExp input="$$9" output="&lt;details&gt;\1&lt;/details&gt;" dest="10">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.kinopoisk.ru\1&lt;/url&gt;" dest="7">
+ <expression repeat="yes" noclean="1">&lt;a href=&quot;([^&quot;]+)&quot; class=all&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;url function=&quot;GMFFR&quot;&gt;\1&lt;/url&gt;" dest="9">
+ <expression repeat="yes" noclean="1">&lt;url&gt;([^&lt;]+)&lt;/url&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GMFR>
+
+ <GMFFR clearbuffers="no" dest="5">
+ <RegExp input="$$1" output="&lt;thumb&gt;http://www.kinopoisk.ru\1&lt;/thumb&gt;" dest="6+">
+ <expression noclean="1">&lt;img.+?src=&apos;([^&apos;]*wallpaper[^&apos;]*)&apos;.+?style=&quot;border:1px solid #777&quot; onLoad=&apos;&apos;&gt;&lt;/a&gt;&lt;/td&gt;</expression>
+ </RegExp>
+ </GMFFR>
+
+
+ <GMP dest="10">
+ <RegExp input="$$9" output="&lt;details&gt;\1&lt;/details&gt;" dest="10">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.kinopoisk.ru\1&lt;/url&gt;" dest="7">
+ <expression repeat="yes" noclean="1">&lt;a href=&quot;([^&quot;]+)&quot;&gt;&lt;img[^&gt;]+alt=&quot;Просмотр постера&quot;&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;url function=&quot;GMPP&quot;&gt;\1&lt;/url&gt;" dest="9">
+ <expression repeat="yes" noclean="1">&lt;url&gt;([^&lt;]+)&lt;/url&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GMP>
+
+ <GMPP clearbuffers="no" dest="5">
+ <RegExp input="$$1" output="&lt;thumb&gt;http://www.kinopoisk.ru\1&lt;/thumb&gt;" dest="6+">
+ <expression noclean="1">&lt;img.+?src=&apos;([^&apos;]*poster[^&apos;]*)&apos;.+?style=&quot;border:1px solid #777&quot; onLoad=&apos;&apos;&gt;&lt;/a&gt;&lt;/td&gt;</expression>
+ </RegExp>
+ </GMPP>
+
+
+ <GetPoster dest="5">
+ <RegExp input="$$6" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetPoster>
+
+ <GetFanart dest="5">
+ <RegExp input="$$6" output="&lt;details&gt;&lt;fanart&gt;\1&lt;/fanart&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetFanart>
+
+
+ <STT dest="10">
+ <RegExp input="$$1" output="\2" dest="8">
+ <expression noclean="2">&lt;table(.*?)Прокат:(.*?)&lt;/table&gt;</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;details&gt;&lt;studio&gt;\1&lt;/studio&gt;&lt;/details&gt;" dest="10">
+ <expression trim="1">&lt;a [^&gt;]*&gt;([^&lt;]+)&lt;/a&gt;</expression>
+ </RegExp>
+ </STT>
+
+ <PEOPLE dest="10">
+ <RegExp input="$$7" output="&lt;details&gt;\1&lt;/details&gt;" dest="10">
+ <!-- actors -->
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression noclean="1">&lt;tr&gt;&lt;td colspan=3&gt;&lt;a name=&quot;actor&quot;&gt;&lt;/td&gt;&lt;/tr&gt;(.*?)&lt;tr&gt;&lt;td colspan=3 style=&quot;border-top:1px solid #ccc&quot;&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;actor&gt;&lt;name&gt;\3&lt;/name&gt;&lt;thumb spoof=&quot;http://www.kinopoisk.ru/&quot;&gt;http://www.kinopoisk.ru/\1&lt;/thumb&gt;&lt;/actor&gt;" dest="7">
+ <expression trim="3" repeat="yes">img src=&quot;([^&quot;]+)&quot; width=52 style=&quot;border:1px solid #ccc&quot;(.+?)a href=&quot;.*?people[^&quot;]*&quot; class=&quot;all&quot;&gt;([^&lt;]+)&lt;/a&gt;</expression>
+ </RegExp>
+
+ <!-- director -->
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression noclean="1">&lt;tr&gt;&lt;td colspan=3&gt;&lt;a name=&quot;director&quot;&gt;&lt;/td&gt;&lt;/tr&gt;(.*?)&lt;tr&gt;&lt;td colspan=3 style=&quot;border-top:1px solid #ccc&quot;&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;director&gt;\3&lt;/director&gt;" dest="7+">
+ <expression trim="3" repeat="yes">img src=&quot;([^&quot;]+)&quot; width=52 style=&quot;border:1px solid #ccc&quot;(.+?)a href=&quot;.*?people[^&quot;]*&quot; class=&quot;all&quot;&gt;([^&lt;]+)&lt;/a&gt;</expression>
+ </RegExp>
+
+ <!-- writers -->
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression noclean="1">&lt;tr&gt;&lt;td colspan=3&gt;&lt;a name=&quot;writer&quot;&gt;&lt;/td&gt;&lt;/tr&gt;(.*?)&lt;tr&gt;&lt;td colspan=3 style=&quot;border-top:1px solid #ccc&quot;&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;credits&gt;\3&lt;/credits&gt;" dest="7+">
+ <expression trim="3" repeat="yes">img src=&quot;([^&quot;]+)&quot; width=52 style=&quot;border:1px solid #ccc&quot;(.+?)a href=&quot;.*?people[^&quot;]*&quot; class=&quot;all&quot;&gt;([^&lt;]+)&lt;/a&gt;</expression>
+ </RegExp>
+
+ <!-- producer -->
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression noclean="1">&lt;tr&gt;&lt;td colspan=3&gt;&lt;a name=&quot;producer&quot;&gt;&lt;/td&gt;&lt;/tr&gt;(.*?)&lt;tr&gt;&lt;td colspan=3 style=&quot;border-top:1px solid #ccc&quot;&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;producer&gt;\3&lt;/producer&gt;" dest="7+">
+ <expression trim="3" repeat="yes">img src=&quot;([^&quot;]+)&quot; width=52 style=&quot;border:1px solid #ccc&quot;(.+?)a href=&quot;.*?people[^&quot;]*&quot; class=&quot;all&quot;&gt;([^&lt;]+)&lt;/a&gt;</expression>
+ </RegExp>
+
+ <expression noclean="1"></expression>
+ </RegExp>
+ </PEOPLE>
+</scraper>
diff --git a/system/scrapers/video/MyMovies.png b/system/scrapers/video/MyMovies.png
new file mode 100644
index 0000000000..b822706a9c
--- /dev/null
+++ b/system/scrapers/video/MyMovies.png
Binary files differ
diff --git a/system/scrapers/video/MyMovies.xml b/system/scrapers/video/MyMovies.xml
new file mode 100644
index 0000000000..1598be8a7e
--- /dev/null
+++ b/system/scrapers/video/MyMovies.xml
@@ -0,0 +1,333 @@
+п»ї<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.1" date="2009-08-08" name="MyMovies.it" content="movies" thumb="MyMovies.png" language="it">
+
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Full Cast Credits&quot; type=&quot;bool&quot; id=&quot;fullcredits&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Full Cast Credits > Get Director(s)&quot; type=&quot;bool&quot; id=&quot;viewDirector&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Full Cast Credits > Get Actors&quot; type=&quot;bool&quot; id=&quot;viewActors&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Full Cast Credits > Get Filmmakers&quot; type=&quot;bool&quot; id=&quot;viewFilmmakers&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Full Cast Credits > Cast Separeted by Fake Actor&quot; type=&quot;bool&quot; id=&quot;fakeactor&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting type=&quot;sep&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Get All Thumbs&quot; type=&quot;bool&quot; id=&quot;thumbs&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Get Trailer&quot; type=&quot;bool&quot; id=&quot;trailer&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Get Critic&quot; type=&quot;bool&quot; id=&quot;critic&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Get Pubblic&quot; type=&quot;bool&quot; id=&quot;public&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Get Forum&quot; type=&quot;bool&quot; id=&quot;forum&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Get Frasi Celebri&quot; type=&quot;bool&quot; id=&quot;frasi_celebri&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Rating x of 10&quot; type=&quot;bool&quot; id=&quot;rating_ten&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting type=&quot;sep&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Director, Critics, and Public Rating&quot; type=&quot;bool&quot; id=&quot;other_rating&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Director, Critics, and Public Rating > Insert into:&quot; type=&quot;labelenum&quot; values=&quot;mpaa|outline|studio&quot; id=&quot;tag_other_rating&quot; default=&quot;mpaa&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="\1" dest="3">
+ <expression noclean="1">(http://www\.mymovies\.it/dizionario/recensione\.asp\?id=[0-9]+)</expression>
+ </RegExp>
+ </NfoUrl>
+
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="http://www.mymovies.it/database/ricerca/?q=\1" dest="3">
+ <expression noclean="1"/>
+ </RegExp>
+ </CreateSearchUrl>
+
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2 (\3, \4)&lt;/title&gt;&lt;url&gt;http://www.mymovies.it/dizionario/recensione.asp?id=\1&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes" noclean="1">&lt;h3 style=&quot;margin:0px;&quot;&gt;[^&lt;]*&lt;a href=&quot;http://www\.mymovies\.it/dizionario/recensione\.asp\?id=([0-9]+)&quot; title=&quot;[^&quot;]+&quot;&gt;([^&lt;]+)&lt;/a&gt;[^7]+&lt;div class=&quot;linkblu2&quot; style=&quot;padding-right:7px; text-align:justify;&quot;&gt;[^&lt;]+Un film di &lt;[ab][&gt; ][^A-Z]*([^&lt;]+)&lt;/[ab]&gt;[^;]+anno=([^&quot;]+)</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetSearchResults>
+
+ <GetDetails clearbuffers="no" dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;&lt;year&gt;\2&lt;/year&gt;" dest="5+">
+ <expression noclean="1">&lt;title&gt;(.+).\((.+)\)&lt;/title&gt;</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression noclean="1">durata ([0-9]*) min\.</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression noclean="1">&lt;a title=&quot;Film ([^&quot;]*)&quot; href=&quot;http://www.mymovies.it/film/([^&quot;]*)&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+
+ <!-- Director(s) -->
+ <RegExp input="$$1" output="\1" dest="4">
+ <expression noclean="1">Un film di (.+)Con &lt;a</expression>
+ </RegExp>
+
+ <RegExp input="$$4" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <expression repeat="yes" noclean="1">[^A-Z]*([^\.^,^&lt;]+)[^\.^,]*[\.,]</expression>
+ </RegExp>
+
+ <!-- Writer(s) -->
+ <RegExp output="&lt;url cache=&quot;$$2-fullcredits.html&quot; function=&quot;GetMovieWriters&quot;&gt;http://www.mymovies.it/cast/?id=$$2&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+
+ <!-- Tagline -->
+ <RegExp input="$$1" output="&lt;tagline&gt;\1&lt;/tagline&gt;" dest="5+">
+ <expression noclean="1">&lt;strong class=&quot;courier&quot; style=&quot;font-size:23px; margin-bottom:10px; color:#ff0066; display:block;&quot;&gt;([^&lt;]+)&lt;/strong&gt;</expression>
+ </RegExp>
+
+ <!-- Rating -->
+ <!-- rating map array -->
+ <RegExp conditional="rating_ten" output="&lt;r&gt;0.1-0.2&lt;/r&gt;&lt;r&gt;0.2-0.4&lt;/r&gt;&lt;r&gt;0.3-0.6&lt;/r&gt;&lt;r&gt;0.4-0.8&lt;/r&gt;&lt;r&gt;0.5-1.0&lt;/r&gt;&lt;r&gt;0.6-1.2&lt;/r&gt;&lt;r&gt;0.7-1.4&lt;/r&gt;&lt;r&gt;0.8-1.6&lt;/r&gt;&lt;r&gt;0.9-1.8&lt;/r&gt;&lt;r&gt;1.0-2.0&lt;/r&gt;&lt;r&gt;1.1-2.2&lt;/r&gt;&lt;r&gt;1.2-2.4&lt;/r&gt;&lt;r&gt;1.3-2.6&lt;/r&gt;&lt;r&gt;1.4-2.8&lt;/r&gt;&lt;r&gt;1.5-3.0&lt;/r&gt;&lt;r&gt;1.6-3.2&lt;/r&gt;&lt;r&gt;1.7-3.4&lt;/r&gt;&lt;r&gt;1.8-3.6&lt;/r&gt;&lt;r&gt;1.9-3.8&lt;/r&gt;&lt;r&gt;2.0-4.0&lt;/r&gt;&lt;r&gt;2.1-4.2&lt;/r&gt;&lt;r&gt;2.2-4.4&lt;/r&gt;&lt;r&gt;2.3-4.6&lt;/r&gt;&lt;r&gt;2.4-4.8&lt;/r&gt;&lt;r&gt;2.5-5.0&lt;/r&gt;&lt;r&gt;2.6-5.2&lt;/r&gt;&lt;r&gt;2.7-5.4&lt;/r&gt;&lt;r&gt;2.8-5.6&lt;/r&gt;&lt;r&gt;2.9-5.8&lt;/r&gt;&lt;r&gt;3.0-6.0&lt;/r&gt;&lt;r&gt;3.1-6.2&lt;/r&gt;&lt;r&gt;3.2-6.4&lt;/r&gt;&lt;r&gt;3.3-6.6&lt;/r&gt;&lt;r&gt;3.4-6.8&lt;/r&gt;&lt;r&gt;3.5-7.0&lt;/r&gt;&lt;r&gt;3.6-7.2&lt;/r&gt;&lt;r&gt;3.7-7.4&lt;/r&gt;&lt;r&gt;3.8-7.6&lt;/r&gt;&lt;r&gt;3.9-7.8&lt;/r&gt;&lt;r&gt;4.0-8.0&lt;/r&gt;&lt;r&gt;4.1-8.2&lt;/r&gt;&lt;r&gt;4.2-8.4&lt;/r&gt;&lt;r&gt;4.3-8.6&lt;/r&gt;&lt;r&gt;4.4-8.8&lt;/r&gt;&lt;r&gt;4.5-9.0&lt;/r&gt;&lt;r&gt;4.6-9.2&lt;/r&gt;&lt;r&gt;4.7-9.4&lt;/r&gt;&lt;r&gt;4.8-9.6&lt;/r&gt;&lt;r&gt;4.9-9.8&lt;/r&gt;&lt;r&gt;5.0-10.0&lt;/r&gt;&lt;r&gt;n.d- &lt;/r&gt;" dest="4">
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!-- Average -->
+ <RegExp input="$$1" output="\1.\2" dest="6">
+ <expression noclean="1">Giudizio medio[^,]+([0-9]),?([0-9]?)/5</expression>
+ </RegExp>
+
+ <RegExp conditional="rating_ten" input="$$4" output="\1" dest="6">
+ <expression noclean="1">$$6-([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="5+">
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!-- Others Rating -->
+ <RegExp conditional="other_rating" input="$$6" output="&lt;$INFO[tag_other_rating]&gt;\1&lt;/$INFO[tag_other_rating]&gt;" dest="5+">
+ <!-- Dizionari -->
+ <RegExp input="$$1" output="Dizionari: \1.\2" dest="6">
+ <expression noclean="1">&lt;b&gt;Dizionari&lt;/b&gt; \(([0-9]+),?([0-9]?)/5\)&lt;br /&gt;</expression>
+ </RegExp>
+ <!-- Critica -->
+ <RegExp input="$$1" output=" / Critica: \1.\2" dest="6+">
+ <expression noclean="1">&lt;b&gt;Critica&lt;/b&gt; \(([0-9]+),?([0-9]?)/5\)&lt;br /&gt;</expression>
+ </RegExp>
+ <!-- Pubblico -->
+ <RegExp input="$$1" output=" / Pubblico: \1.\2" dest="6+">
+ <expression noclean="1">&lt;b&gt;Pubblico&lt;/b&gt; \(([0-9]+),?([0-9]?)/5\)&lt;br /&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!-- Cast -->
+ <RegExp conditional="!fullcredits" input="$$6" output="\1" dest="5+">
+ <RegExp input="$$1" output="\1" dest="4">
+ <expression noclean="1">Un film di .*Con (.*\.)[^G]+Genere &lt;a</expression>
+ </RegExp>
+ <RegExp input="$$4" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;" dest="6">
+ <expression repeat="yes" noclean="1">[^A-Z]*([^\.^,^&lt;]+)[^\.^,]*[\.,]</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!-- Full Cast -->
+ <RegExp conditional="fullcredits" output="&lt;url cache=&quot;$$2-fullcredits.html&quot; function=&quot;GetMovieCast&quot;&gt;http://www.mymovies.it/cast/?id=$$2&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+
+ <!-- Thumb -->
+ <RegExp conditional="!thumbs" input="$$1" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="5+">
+ <expression noclean="1">&lt;a title=&quot;Locandina[^&quot;]+&quot; href=&quot;[^&quot;]+&quot;&gt;&lt;img style=&quot;border:solid 1px \#AEAEAE; padding:3px;&quot; src=&quot;([^&quot;]+)&quot; width=&quot;150px&quot; alt=&quot;Locandina[^&quot;]+&quot; /&gt;&lt;/a&gt;</expression>
+ </RegExp>
+ <!-- else All Thumbs -->
+ <RegExp conditional="thumbs" output="&lt;url function=&quot;GetMovieThumbs&quot;&gt;http://www.mymovies.it/poster/?id=$$2&lt;/url&gt;" dest="5+">
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!-- Trailer: not always present -->
+ <RegExp conditional="trailer" input="$$1" output="&lt;url function=&quot;GetMovieTrailer&quot;&gt;\1&lt;/url&gt;" dest="5+">
+ <expression>&lt;span class=&quot;rec_link_disattivo&quot;&gt;&lt;a title=&quot;[^&quot;]+&quot; href=&quot;([^&quot;]+)&quot;&gt;Trailer&lt;/a&gt;&lt;/span&gt;</expression>
+ </RegExp>
+
+ <!-- Plot: It is used for report many information...It will be write on correct buffer (5) at the end -->
+ <RegExp input="$$1" output="\1" dest="10">
+ <expression>&lt;p style=&quot;text-align:justify;&quot;&gt;(.+?)&lt;/p&gt;</expression>
+ </RegExp>
+
+ <!-- Plot: all that you want append... -->
+ <RegExp conditional="critic" output="&lt;url function=&quot;GetMovieCritic&quot;&gt;http://www.mymovies.it/recensioni/?id=$$2&lt;/url&gt;" dest="5+">
+ <expression noclean="1"></expression>
+ </RegExp>
+ <RegExp conditional="public" output="&lt;url function=&quot;GetMoviePublic&quot;&gt;http://www.mymovies.it/pubblico/?id=$$2&lt;/url&gt;" dest="5+">
+ <expression noclean="1"></expression>
+ </RegExp>
+ <RegExp conditional="forum" output="&lt;url function=&quot;GetMovieForum&quot;&gt;http://www.mymovies.it/forum/?id=$$2&lt;/url&gt;" dest="5+">
+ <expression noclean="1"></expression>
+ </RegExp>
+ <RegExp conditional="frasi_celebri" output="&lt;url function=&quot;GetMovieFrasiCelebri&quot;&gt;http://www.mymovies.it/battute/?id=$$2&lt;/url&gt;" dest="5+">
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!-- Plot: ...at the end -->
+ <!-- non serve a un cazzo l'url (giГ  cached), ma ГЁ l'unico modo per vedere il buffer 10 istanziato nella GetDetails, e i buffer 11,12,13 istanziati nelle altre fuzioni -->
+ <RegExp output="&lt;url cache=&quot;$$2-fullcredits.html&quot; function=&quot;AppendToPlot&quot;&gt;http://www.mymovies.it/cast/?id=$$2&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+
+ <GetMovieWriters clearbuffers="no" dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="2">
+ <expression repeat="yes" noclean="1">http://www\.mymovies\.it/biografia/\?s=[^&gt;]+&gt;([^&lt;]+)[^\(]+\(Soggetto\)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetMovieWriters>
+
+ <GetMovieTrailer clearbuffers="no" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;trailer&gt;\1&lt;/trailer&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1">flashvars=&quot;file=([^&amp;]+)</expression>
+ </RegExp>
+ </GetMovieTrailer>
+
+ <GetMovieThumbs clearbuffers="no" dest="5">
+ <RegExp input="$$3" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <!-- Mask unnecessary part of source...is necessary when there is one thumb only -->
+ <RegExp input="$$1" output="\1" dest="2">
+ <expression noclean="1">&lt;table cellpadding=&quot;0&quot; cellspacing=&quot;3&quot; style=&quot;width:100%&quot;&gt;(.+?)&lt;/table&gt;</expression>
+ </RegExp>
+ <!-- Match All img -->
+ <RegExp input="$$2" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="3">
+ <expression repeat="yes" noclean="1">&lt;img[^/]+src=&quot;([^&quot;]+)&quot; /&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetMovieThumbs>
+
+ <GetMovieCast clearbuffers="no" dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <!-- Director(s) -->
+ <RegExp conditional="viewDirector" input="$$3" output="\1" dest="2">
+ <!-- Fake Actor for Section delimiter: Regia -->
+ <RegExp conditional="fakeactor" output="&lt;actor&gt;&lt;name&gt;.Regia&lt;/name&gt;&lt;/actor&gt;" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ <!-- Mask unnecessary part of source -->
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">&lt;b&gt;Regia&lt;/b&gt;[^&lt;]*&lt;/div&gt;(.*?)&lt;div class=&quot;linkblu&quot; style=&quot;padding-left:12px; padding-right:7px; text-align:left; background-color:\#E1E1E1; margin-left:5px; margin-top:20px; font-size:120%;&quot;&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;thumb&gt;\1&lt;/thumb&gt;&lt;name&gt;\2&lt;/name&gt;&lt;role&gt;Regista&lt;/role&gt;&lt;/actor&gt;" dest="3+">
+ <expression repeat="yes" noclean="1">&lt;div class=&quot;linkblu&quot; style=&quot;padding:3px; padding-left:20px;&quot;&gt;[^&lt;]+(?:&lt;a href=&quot;[^&quot;]+&quot; title=&quot;[^&quot;]+&quot;&gt;&lt;img style=&quot;float:left; margin-right:3px;&quot; src=&quot;([^&quot;]+)&quot; width=&quot;80&quot; alt=&quot;[^&quot;]+&quot; /&gt;&lt;/a&gt;)?[^\?]+\?[^&gt;]+&gt;([^&lt;]+)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!-- Actors -->
+ <RegExp conditional="viewActors" input="$$3" output="\1" dest="2">
+ <!-- Fake Actor for Section delimiter: Cast artistico -->
+ <RegExp conditional="fakeactor" output="&lt;actor&gt;&lt;name&gt;.Cast artistico&lt;/name&gt;&lt;/actor&gt;" dest="3+">
+ <expression noclean="1"></expression>
+ </RegExp>
+ <!-- Mask unnecessary part of source -->
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">&lt;b&gt;Cast artistico&lt;/b&gt;[^&lt;]*&lt;/div&gt;(.*?)(?(?=&lt;div class=&quot;linkblu&quot; style=&quot;padding-left:12px; padding-right:7px; text-align:left; background-color:\#E1E1E1; margin-left:5px; margin-top:20px; font-size:120%;&quot;&gt;)&lt;div class=&quot;linkblu&quot; style=&quot;padding-left:12px; padding-right:7px; text-align:left; background-color:\#E1E1E1; margin-left:5px; margin-top:20px; font-size:120%;&quot;&gt;|&lt;div style=&quot;height:17px; clear:both;&quot;&gt;&lt;/div&gt;)</expression>
+ </RegExp>
+ <!-- \1: thumb (opt) \2: name \3: role (opt) -->
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;thumb&gt;\1&lt;/thumb&gt;&lt;name&gt;\2&lt;/name&gt;&lt;role&gt;\3&lt;/role&gt;&lt;/actor&gt;" dest="3+">
+ <expression repeat="yes" noclean="1">&lt;div class=&quot;linkblu&quot; style=&quot;padding:3px; padding-left:20px;&quot;&gt;[^&lt;]+(?:&lt;a href=&quot;[^&quot;]+&quot; title=&quot;[^&quot;]+&quot;&gt;&lt;img style=&quot;float:left; margin-right:3px;&quot; src=&quot;([^&quot;]+)&quot; width=&quot;80&quot; alt=&quot;[^&quot;]+&quot; /&gt;&lt;/a&gt;)?[^\?]+\?[^&gt;]+&gt;([^&lt;]+)&lt;/a&gt;[^%]+(?:&lt;span style=&quot;font-size:120%; padding-left:10px;&quot;&gt;interpreta &lt;strong&gt;&lt;em&gt;([^&lt;]+)&lt;/strong&gt;&lt;/em&gt;&lt;/span&gt;)?[^&lt;]+&lt;span style=&quot;font-size:120%;&quot;&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!-- Filmmakers -->
+ <RegExp conditional="viewFilmmakers" input="$$3" output="\1" dest="2">
+ <!-- Fake Actor for Section delimiter: Filmmakers -->
+ <RegExp conditional="fakeactor" output="&lt;actor&gt;&lt;name&gt;.Filmmakers&lt;/name&gt;&lt;/actor&gt;" dest="3+">
+ <expression noclean="1"></expression>
+ </RegExp>
+ <!-- Mask unnecessary part of source -->
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">&lt;b&gt;Filmmakers&lt;/b&gt;[^&lt;]*&lt;/div&gt;(.*?)&lt;div style=&quot;background-color:\#eeeeee; color:\#00336C; font-weight:bold; padding-left:5px;&quot; &gt;</expression>
+ </RegExp>
+ <!-- \1: thumb (opt) \2: name \3: role -->
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;thumb&gt;\1&lt;/thumb&gt;&lt;name&gt;\2&lt;/name&gt;&lt;role&gt;\3&lt;/role&gt;&lt;/actor&gt;" dest="3+">
+ <expression repeat="yes" noclean="1">&lt;div class=&quot;linkblu&quot; style=&quot;padding:3px; padding-left:20px;&quot;&gt;[^&lt;]+(?:&lt;a href=&quot;[^&quot;]+&quot; title=&quot;[^&quot;]+&quot;&gt;&lt;img style=&quot;float:left; margin-right:3px;&quot; src=&quot;([^&quot;]+)&quot; width=&quot;80&quot; alt=&quot;[^&quot;]+&quot; /&gt;&lt;/a&gt;)?[^\?]+\?[^&gt;]+&gt;([^&lt;]+)&lt;/a&gt;[^\(]+\(([^\)]+)\)&lt;/span&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetMovieCast>
+
+ <!-- Mancano i commenti estesi -->
+ <GetMovieCritic clearbuffers="no" dest="5">
+ <RegExp input="$$2" output="\n\n:: Critica\n\1" dest="11">
+ <RegExp input="$$1" output="\n\1 - \2\n\3\n" dest="2">
+ <expression repeat="yes">&lt;a href=&quot;http://www.mymovies.it/dizionario/critica.asp\?id=[^&quot;]+&quot;&gt;([^&lt;]+)&lt;/a&gt;[^&lt;]*&lt;strong&gt;&lt;em&gt;([^&lt;]+)&lt;/em&gt;&lt;/strong&gt;.+?style=&quot;color:\#333333; margin-bottom:10px;&quot;&gt;(.+?)&lt;/span&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetMovieCritic>
+
+ <!-- Mancano i commenti estesi -->
+ <GetMoviePublic clearbuffers="no" dest="5">
+ <RegExp input="$$2" output="\n\n:: Pubblico\n\1" dest="12">
+ <RegExp input="$$1" output="\1\n" dest="2">
+ <expression repeat="yes">&lt;div id=&quot;parziale[^&quot;]+&quot; class=&quot;linkrosa&quot; style=&quot;color:\#333333; margin-bottom:10px;&quot;&gt;(.+?)&lt;/div&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetMoviePublic>
+
+ <!-- Mancano i commenti estesi -->
+ <GetMovieForum clearbuffers="no" dest="5">
+ <RegExp input="$$2" output="\n\n:: Forum\n\1" dest="13">
+ <RegExp input="$$1" output="\1\n" dest="2">
+ <expression repeat="yes">&lt;div id=&quot;parziale[^&quot;]+&quot; class=&quot;linkrosa&quot; style=&quot;color:\#333333; margin-bottom:10px;&quot;&gt;(.+?)&lt;/div&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetMovieForum>
+
+ <GetMovieFrasiCelebri clearbuffers="no" dest="5">
+ <RegExp input="$$2" output="\n\n:: Frasi Celebri\n\1" dest="14">
+ <RegExp input="$$1" output="\1\n" dest="2">
+ <expression repeat="yes">&lt;div style=&quot;text-align:justify;&quot;&gt;(.+?)&lt;/div&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetMovieFrasiCelebri>
+
+ <AppendToPlot clearbuffers="no" dest="5">
+ <RegExp input="$$10$$11$$12$$13$$14" output="&lt;details&gt;&lt;plot&gt;\1&lt;/plot&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </AppendToPlot>
+</scraper>
diff --git a/system/scrapers/video/adultcdmovies.jpg b/system/scrapers/video/adultcdmovies.jpg
new file mode 100644
index 0000000000..a6310957d1
--- /dev/null
+++ b/system/scrapers/video/adultcdmovies.jpg
Binary files differ
diff --git a/system/scrapers/video/adultcdmovies.xml b/system/scrapers/video/adultcdmovies.xml
new file mode 100644
index 0000000000..0c87de6256
--- /dev/null
+++ b/system/scrapers/video/adultcdmovies.xml
@@ -0,0 +1,67 @@
+<scraper framework="1.0" date="2009-05-22" name="Adult CD Movies" content="movies" thumb="adultcdmovies.jpg" language="en">
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="http://www.adultcdmovies.net/\1.aspx" dest="3">
+ <expression noclean="1">adultcdmovies.net/(.*).aspx</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateSearchUrl dest="2">
+ <RegExp input="$$1" output="http://www.adultcdmovies.net/e-pmsearch.aspx?SearchType=0&amp;SearchTerm=\1" dest="2">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url&gt;http://www.adultcdmovies.net/\1.aspx?&lt;/url&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes">&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;(adult-dvd-[^genre].[^\.]*)\.aspx\?&quot;&gt;(.[^/]*)&lt;/a&gt;&lt;/td&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression>&lt;title&gt;(.*)&lt;/title&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>Movie Year: ([0-9]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;director&gt;\1 \2&lt;/director&gt;" dest="5+">
+ <expression>Director:&lt;.[^&gt;]*&gt;(.[^/]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;manufacturer&gt;\1 \2&lt;/manufacturer&gt;" dest="5+">
+ <expression>Studio: &lt;.[^&gt;]*&gt;(.[^/]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;genre&gt;Adult&lt;/genre&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression noclean="1">Categories &amp;amp; Genres:(.*)Starring</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes">&lt;a href=&quot;adult-dvd-genre[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>&lt;/div&gt;&lt;hr style=&quot;clear:both&quot; /&gt;([^&lt;]*)&lt;p align=&quot;left&quot;&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb spoof=&quot;http://www.adultcdmovies.net&quot;&gt;http://www.adultcdmovies.net/images/Product/medium/\1.jpg&lt;/thumb&gt;&lt;thumb spoof=&quot;http://www.adultcdmovies.net&quot;&gt;http://www.adultcdmovies.net/images/Product/large/\1.jpg&lt;/thumb&gt;" dest="5+">
+ <expression>images/Product/medium/([0-9]+)\.jpg</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;genre&gt;Adult\1&lt;/genre&gt;" dest="5+">
+ <RegExp input="$$6" output=" / \1" dest="7">
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression>Categories &amp;amp; Genres:(.*)Director:</expression>
+ </RegExp>
+ <expression repeat="yes">&lt;a href=&quot;.[^&quot;]*&quot;&gt;(.[^/]*) DVD&lt;/a&gt;</expression>
+ </RegExp>
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression clear="yes">Starring:(.*)E-mail this movie to a friend</expression>
+ </RegExp>
+ <expression repeat="yes">\?&quot;&gt;(.[^/]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+</scraper>
diff --git a/system/scrapers/video/adultdvdempire.jpg b/system/scrapers/video/adultdvdempire.jpg
new file mode 100644
index 0000000000..9f9e944bd5
--- /dev/null
+++ b/system/scrapers/video/adultdvdempire.jpg
Binary files differ
diff --git a/system/scrapers/video/adultdvdempire.xml b/system/scrapers/video/adultdvdempire.xml
new file mode 100644
index 0000000000..36781ba3f1
--- /dev/null
+++ b/system/scrapers/video/adultdvdempire.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<scraper framework="1.1" date="2009-09-19" name="Adult DVD Empire" content="movies" thumb="adultdvdempire.jpg" language="en">
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.adultdvdempire.com/itempage.aspx?item_id=\1&lt;/url&gt;" dest="3">
+ <expression noclean="1">adultdvdempire.com/itempage.aspx?item_id=([0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.adultdvdempire.com/SearchTitlesPage.aspx?SearchString=\1&lt;/url&gt;" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+
+ <GetSearchResults dest="6">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="6">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url&gt;http://www.adultdvdempire.com/\1&lt;/url&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes">ListItem_ItemTitle&quot;&gt;&lt;a href=&quot;/([^&quot;]*)&quot;&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;thumb&gt;http://\1.dvdempire.com/res/movies/\2h.jpg&lt;/thumb&gt;" dest="5+">
+ <expression>BoxCover_Container&quot;&gt;[^&gt;]*&gt;&lt;img src=&quot;http://(.*?).dvdempire.com/res/movies/([^m]*)</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;thumb&gt;http://\1.dvdempire.com/res/movies/\2bh.jpg&lt;/thumb&gt;" dest="5+">
+ <expression>BoxCover_Container&quot;&gt;[^&gt;]*&gt;&lt;img src=&quot;http://(.*?).dvdempire.com/res/movies/([^m]*)</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5+">
+ <expression>Item_Title&quot;&gt;([^&lt;]*)</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="5+">
+ <expression>StudioProductionRating&quot;&gt;([^&lt;]*)</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>Year: ([0-9]*)</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;tagline&gt;\1&lt;/tagline&gt;&lt;plot&gt;\2&lt;/plot&gt;" dest="5+">
+ <expression>InfoTagLine&quot;&gt;([^&lt;]*)&lt;[^&gt;]*&gt;[^ ]*([^&lt;]*)&lt;</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>Item_InfoContainer&quot;&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;actor&gt;&lt;name&gt;\3&lt;/name&gt;&lt;thumb&gt;http://images.dvdempire.com/pornstar/actors/\1.jpg&lt;/thumb&gt;&lt;/actor&gt;" dest="5+">
+ <expression repeat="yes">&lt;a href=&quot;/([0-9]*)/([^&quot;]*)-Pornstars.html&quot;&gt;([^&lt;]*)</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes">media_id=[^i]*item_id=[^&gt;]*&gt;([^&lt;]*)</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression>&gt;Length: ([^&lt;]*)&lt;</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;" dest="5+">
+ <expression>&gt;Rating: ([^&lt;]*)</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;director&gt;\3&lt;/director&gt;" dest="5+">
+ <expression repeat="yes">&lt;a href=&quot;/([0-9]*)/([^&quot;]*)-Directors.html&quot;&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+</scraper>
diff --git a/system/scrapers/video/adultfilmdatabase.xml b/system/scrapers/video/adultfilmdatabase.xml
new file mode 100644
index 0000000000..31a10c5fdd
--- /dev/null
+++ b/system/scrapers/video/adultfilmdatabase.xml
@@ -0,0 +1,61 @@
+<scraper framework="1.0" date="2009-05-22" name="adultfilm database" content="movies" thumb="AdultFilmdatabase.gif" language="en">
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.adultfilmdatabase.com/video.cfm?videoid=\1&lt;url&gt;" dest="3">
+ <expression noclean="1">adultfilmdatabase.com/video.cfm?videoid=([0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url spoof=&quot;http://www.adultfilmdatabase.com&quot; post=&quot;true&quot;&gt;http://www.adultfilmdatabase.com/lookup.cfm?SearchType=Video&amp;amp;Action=Lookup&amp;amp;Find=\1&lt;/url&gt;" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="6">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="6">
+ <RegExp input="$$1" output="\1" dest="4">
+ <expression>&lt;h2&gt;([^&lt;]*)&lt;/h2&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;$$4&lt;/title&gt;&lt;url&gt;http://www.adultfilmdatabase.com/video.cfm?videoid=\1&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;" dest="5">
+ <expression>/Front/([0-9]*)\.jpg</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url&gt;http://www.adultfilmdatabase.com/video.cfm?videoid=\1&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes">&lt;a HREF=&quot;/video\.cfm\?videoid=([0-9]*)&quot;&gt;&lt;U&gt;([^&lt;]*)&lt;/U&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;thumb&gt;http://www.adultfilmdatabase.com\1&lt;/thumb&gt;" dest="5">
+ <expression>(/Graphics/Boxes/[0-9]*/Front/$$2\.jpg)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5+">
+ <expression trim="1" noclean="1">&lt;h2&gt;([^&lt;]*)&lt;/h2&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;" dest="5+">
+ <expression repeat="yes">&lt;a HREF=&quot;/actor\.cfm\?actorid=[0-9]*&quot;&gt;&lt;U&gt;([^&lt;]*)&lt;/U&gt;&lt;/a&gt;&lt;br&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;runtime&gt;\1 min&lt;/runtime&gt;" dest="5+">
+ <expression trim="1">Length:&lt;/td&gt;&lt;td STYLE=&quot;font-size:11px;padding-left: 3px;&quot; WIDTH=&quot;100%&quot;&gt;([0-9]+)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>Year:&lt;/td&gt;&lt;td STYLE=&quot;font-size:11px;padding-left: 3px;&quot; WIDTH=&quot;100%&quot;&gt;([0-9]+)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;genre&gt;Adult&lt;/genre&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression trim="1">Genres:&lt;/td&gt;[^&lt;]*&lt;td STYLE=&quot;font-size:11px;padding-left: 3px;&quot; WIDTH=&quot;100%&quot;&gt;([^&lt;]*)&lt;/td&gt;</expression>
+ </RegExp>
+ <expression repeat="yes" trim="1">([a-zA-Z ]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>&lt;tr&gt;&lt;td STYLE=&quot;font-size:9pt;&quot; COLSPAN=&quot;2&quot;&gt;&lt;BR&gt;([^&lt;]*)&lt;/td&gt;&lt;/tr&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <expression>/director\.cfm\?directorid=281&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+</scraper>
diff --git a/system/scrapers/video/allocine.jpg b/system/scrapers/video/allocine.jpg
new file mode 100644
index 0000000000..eb8aae9c42
--- /dev/null
+++ b/system/scrapers/video/allocine.jpg
Binary files differ
diff --git a/system/scrapers/video/allocine.xml b/system/scrapers/video/allocine.xml
new file mode 100644
index 0000000000..fdc6a70336
--- /dev/null
+++ b/system/scrapers/video/allocine.xml
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<scraper framework="1.1" date="2009-08-08" name="allocine.fr" content="movies" thumb="allocine.jpg" language="fr">
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Activer les images HD et photos du film&quot; type=&quot;bool&quot; id=&quot;GetThumbnail&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;setting label=&quot;Activer les Informations du film&quot; type=&quot;bool&quot; id=&quot;info&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;setting label=&quot;Activer les Vignettes d'acteurs&quot; type=&quot;bool&quot; id=&quot;actor&quot; default=&quot;falsetrue&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;setting label=&quot;Activer les Fanart&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="http://www.allocine.fr/film/fichefilm_gen_cfilm=\1.html" dest="3">
+ <expression clear="yes" noclean="1">allocine\.fr/film/fichefilm_gen_cfilm=([0-9]*)\.html</expression>
+ </RegExp>
+ </NfoUrl>
+
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="http://www.allocine.fr/recherche/default.html?motcle=\1&amp;rub=1&amp;page=1" dest="3">
+ <expression>([^\(]+)</expression>
+ </RegExp>
+ </CreateSearchUrl>
+
+ <GetSearchResults dest="2">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="2">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url&gt;http://www.allocine.fr/film/fichefilm_gen_cfilm=\1.html&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes">&lt;h4&gt;&lt;a href=&quot;/film/fichefilm_gen_cfilm=([0-9]+)\.html&quot; class=&quot;link1&quot;&gt;([^;#]*)&lt;/a</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+
+ <GetDetails clearbuffers="no" dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <!-- TITLE -->
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression trim="1" noclean="1">&lt;title&gt;(.*?) \- AlloCin</expression>
+ </RegExp>
+ <!-- STUDIO -->
+ <RegExp conditional="info" input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="5+">
+ <expression>Distribu. par [^&gt;]*&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <!-- GENRE -->
+ <RegExp conditional="info" input="$$1" output="\1" dest="7">
+ <expression noclean="1">Genre :([^:]*):</expression>
+ </RegExp>
+
+ <RegExp conditional="info" input="$$6" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <RegExp input="$$7" output=" / \1" dest="6">
+ <expression repeat="yes" noclean="1">&lt;a href[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression> / (.*)</expression>
+ </RegExp>
+ <!-- YEAR -->
+ <RegExp conditional="info" input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>&gt;Ann.e de production : ([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <!-- DIRECTOR -->
+ <RegExp conditional="info" input="$$1" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <expression>R.alis. par &lt;[^&gt;]*&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <!-- RUNTIME -->
+ <RegExp conditional="info" input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression>Dur.e : ([^.]*)</expression>
+ </RegExp>
+ <!-- RATING VOTES -->
+ <RegExp conditional="info" input="$$1" output="\1#\2" dest="7">
+ <expression>&lt;h4&gt;Note moyenne : &lt;([^&gt;]*)&gt;[^0-9]*([0-9]*)</expression>
+ </RegExp>
+
+ <RegExp conditional="info" input="$$7" output="&lt;rating&gt;\1.toile(s)&lt;/rating&gt;&lt;votes&gt;\2&lt;/votes&gt;" dest="5+">
+ <expression>class=&quot;etoile_([0-9]*)&quot;[^#]*#([0-9]*)</expression>
+ </RegExp>
+ <!-- MPAA -->
+ <RegExp conditional="info" input="$$1" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;" dest="5+">
+ <expression>N. de visa[^&gt;]*&gt;[^&gt;]*&gt;[^&gt;]*&gt;[^&gt;]*&gt;[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <!-- GetTagline -->
+ <RegExp conditional="info" input="$$1" output="&lt;url function=&quot;GetTagline&quot;&gt;http://www.allocine.fr/film/revuedepresse_gen_cfilm=\1.html&lt;/url&gt;" dest="5+">
+ <expression noclean="1">revuedepresse_gen_cfilm=([0-9]*)</expression>
+ </RegExp>
+ <!-- GetCredits -->
+ <RegExp conditional="info" input="$$1" output="&lt;url function=&quot;GetCredits&quot;&gt;http://www.allocine.fr/film/casting_gen_cfilm=\1.html&lt;/url&gt;" dest="5+">
+ <expression>casting_gen_cfilm=([0-9]*)</expression>
+ </RegExp>
+ <!-- GetActor -->
+ <RegExp conditional="info" input="$$1" output="&lt;url function=&quot;GetActor&quot;&gt;http://www.allocine.fr/film/casting_gen_cfilm=\1.html&lt;/url&gt;" dest="5+">
+ <expression>casting_gen_cfilm=([0-9]*)</expression>
+ </RegExp>
+ <!-- OUTLINE -->
+ <RegExp conditional="info" input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>&lt;td valign=&quot;top&quot; style=&quot;padding:10 0 0 0&quot;&gt;&lt;div align=&quot;justify&quot;&gt;&lt;h4&gt;([^\n]*)</expression>
+ </RegExp>
+ <!-- PLOT -->
+ <RegExp conditional="info" input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>&lt;td valign=&quot;top&quot; style=&quot;padding:10 0 0 0&quot;&gt;&lt;div align=&quot;justify&quot;&gt;&lt;h4&gt;([^#]*)&lt;/h4&gt;&lt;/div&gt;&lt;/td&gt;[\n\r\t]*&lt;/tr&gt;[\n\r\t]*&lt;tr&gt;[\n\r\t]*&lt;td valign</expression>
+ </RegExp>
+ <!-- Fanart -->
+ <RegExp input="$$1" output="&lt;fanart&gt;\1&lt;/fanart&gt;" dest="12+">
+ <expression>&quot;([^&quot;]*)&quot; border=&quot;0&quot; alt=&quot;&quot; class=&quot;affichette</expression>
+ </RegExp>
+
+ <RegExp conditional="fanart" input="$$1" output="&lt;url cache=&quot;$$2-fanart.html&quot;function=&quot;GetFanart&quot;&gt;http://www.allocine.fr/film/galerievignette_gen_cfilm=\1.html&lt;/url&gt;" dest="5+">
+ <expression>galerievignette_gen_cfilm=([0-9]*)</expression>
+ </RegExp>
+ <!-- THUMB -->
+ <RegExp input="$$3" output="&lt;url function=&quot;Getallocine&quot; cache=&quot;$$2.html&quot;&gt;\1&lt;/url&gt;" dest="5+">
+ <expression noclean="1"></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+
+ <GetFanart dest="5">
+ <RegExp input="$$10$$12" output="&lt;details&gt;&lt;fanart&gt;\1&lt;/fanart&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1/rsz/434/x/x/x/medias" dest="9+">
+ <expression>var CRP_PATH = &quot;([^&quot;]*)/crp/80/80/x/x/medias&quot;</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;thumb&gt;$$9\1&lt;/thumb&gt;" dest="10+">
+ <expression repeat="yes" noclean="1">&quot;fichier&quot;:&quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetFanart>
+
+ <Getallocine dest="5">
+ <RegExp input="$$10$$11" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb&gt;http://a69.g.akamai.net/n/69/10688/v1/img5.allocine.fr/acmedia/medias/nmedia/\1&lt;/thumb&gt;" dest="11+">
+ <expression noclean="1">&lt;img src=&quot;http://a69.g.akamai.net/n/69/10688/v1/img5.allocine.fr/acmedia/medias/nmedia/([^&quot;]+)&quot; [^&gt;]*&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </Getallocine>
+
+ <GetCredits clearbuffers="no" dest="5">
+ <RegExp input="$$3" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">Sc.nario([^(]*)Equipe technique</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="3+">
+ <RegExp input="$$7" output=" / \1" dest="6">
+ <expression repeat="yes" noclean="1">&gt;([^&lt;]*)&lt;/a</expression>
+ </RegExp>
+ <expression noclean="1"> / (.*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetCredits>
+
+ <GetActor clearbuffers="no" dest="5">
+ <RegExp input="$$3" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">&lt;b&gt;Acteurs&lt;/b&gt;(.*)&lt;b&gt;Production&lt;/b&gt;</expression>
+ </RegExp>
+
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;name&gt;\3&lt;/name&gt;&lt;role&gt;\1&lt;/role&gt;&lt;/actor&gt;" dest="3+">
+ <expression repeat="yes" noclean="1,2,3">&lt;h5&gt;([^&lt;]*)&lt;/h5&gt;&lt;/td&gt;[^&lt;]*&lt;[^&gt;]*&gt;&lt;h5&gt;&lt;a href=&quot;/([^&quot;]*)&quot;[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+
+ <RegExp conditional="actor" input="$$6" output="&lt;url function=&quot;GetActorThumb&quot;&gt;http://www.allocine.fr/personne/fichepersonne_gen_cpersonne=\2.html&lt;/url&gt;&lt;id&gt;\2&lt;/id&gt;\n" dest="3+">
+ <expression repeat="yes" noclean="1,2,3" >&lt;h5&gt;([^&lt;]*)&lt;/h5&gt;&lt;/td&gt;[^&lt;]*&lt;[^&gt;]*&gt;&lt;h5&gt;&lt;a href=&quot;/personne/fichepersonne_gen_cpersonne=([0-9]*).html&quot;[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetActor>
+
+ <GetActorThumb clearbuffers="no" dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp conditional="actor" input="$$1" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="3">
+ <expression>src=&quot;([^&quot;]*)&quot; width=&quot;120&quot; height=&quot;160&quot; border=&quot;0&quot;&gt;&lt;br /&gt;</expression>
+ </RegExp>
+
+ <RegExp conditional="actor" input="$$1" output="&lt;name&gt;\1&lt;/name&gt;" dest="4">
+ <expression>&lt;title&gt;([^&lt;]*)</expression>
+ </RegExp>
+
+ <RegExp conditional="actor" input="$$1" output="&lt;actor&gt;$$3$$4&lt;role&gt;test&lt;/role&gt;&lt;/actor&gt;" dest="2+">
+ <expression>src=&quot;([^&quot;]*)&quot; width=&quot;120&quot; height=&quot;160&quot; border=&quot;0&quot;&gt;&lt;br /&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetActorThumb>
+
+ <GetTagline clearbuffers="no" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;tagline&gt;\1&lt;/tagline&gt;&lt;/details&gt;" dest="5+">
+ <expression clean="1" trim="1">&lt;div align=&quot;justify&quot; style=&quot;padding: 5 0 5 0&quot;&gt;&lt;h4&gt;([^&lt;]*)</expression>
+ </RegExp>
+ </GetTagline>
+</scraper>
+
diff --git a/system/scrapers/video/amazonuk.png b/system/scrapers/video/amazonuk.png
new file mode 100644
index 0000000000..e872b16315
--- /dev/null
+++ b/system/scrapers/video/amazonuk.png
Binary files differ
diff --git a/system/scrapers/video/amazonuk.xml b/system/scrapers/video/amazonuk.xml
new file mode 100644
index 0000000000..0bf5626b7e
--- /dev/null
+++ b/system/scrapers/video/amazonuk.xml
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Initial basic version doing Studio and Thumb believed to have been written by C-Quel -->
+<!-- Then updated by John Lockwood to scrape Title, Year, MPAA, Runtime, Rating, Votes, Plot, Actors, Directors -->
+<!-- This version 1.1 dated 12/01/09 includes fix by C-Quel for processing results from Amazon to match recent change -->
+<!-- Version 1.1 also now supports the Writers field and fixes an issue to do with film titles -->
+<scraper framework="1.0" date="2009-05-22" content="movies" name="Amazon UK" thumb="amazonuk.png" language="en">
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.amazon.co.uk/s/ref=nb_ss_d_h_?url=search-alias%3Ddvd&amp;amp;field-keywords=\1&lt;/url&gt;" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url&gt;\1&lt;/url&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes" clear="yes" noclean="1">productTitle&quot;&gt;&lt;a href=&quot;([^&quot;]*)&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression clear="yes" noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails clearbuffers="no" dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression noclean="1" trim="1">&lt;title&gt;[Amazon.co.uk: ]*([^\:\(]*) </expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression trim="1">[ \[\(]([0-9]{4})[ \]\)][^&lt;]*&lt;/span&gt;</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;top250&gt;\1&lt;/top250&gt;" dest="5+">
+ <expression>Top 250: #([0-9]*)&lt;/a&gt;</expression>
+ </RegExp>
+
+ <RegExp input="$$9" output="&lt;mpaa&gt;Exempt&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;b&gt;Classification:&lt;/b&gt;.*(Exempt)</expression>
+ </RegExp>
+ <expression>(exempt)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;mpaa&gt;U&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;b&gt;Classification:&lt;/b&gt;[^_]*/(u)-rating</expression>
+ </RegExp>
+ <expression>(u)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;mpaa&gt;Uc&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;b&gt;Classification:&lt;/b&gt;[^_]*/(u[cC])-rating</expression>
+ </RegExp>
+ <expression>(uc)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;mpaa&gt;12A&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;b&gt;Classification:&lt;/b&gt;[^_]*/(12[aA])-rating</expression>
+ </RegExp>
+ <expression>(12a)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;mpaa&gt;12&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;b&gt;Classification:&lt;/b&gt;[^_]*/(12)-rating</expression>
+ </RegExp>
+ <expression>(12)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;mpaa&gt;15&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;b&gt;Classification:&lt;/b&gt;[^_]*/(15)-rating</expression>
+ </RegExp>
+ <expression>(15)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;mpaa&gt;PG&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;b&gt;Classification:&lt;/b&gt;[^_]*/(pg)-rating</expression>
+ </RegExp>
+ <expression>(pg)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;mpaa&gt;18&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;b&gt;Classification:&lt;/b&gt;[^_]*/(18)-rating</expression>
+ </RegExp>
+ <expression>(18)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;mpaa&gt;R18&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;b&gt;Classification:&lt;/b&gt;[^_]*/([rR]18)-rating</expression>
+ </RegExp>
+ <expression>(R18)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;mpaa&gt;UNRATED&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;b&gt;Classification:&lt;/b&gt;[^_]*/(unrated)-rating</expression>
+ </RegExp>
+ <expression>(unrated)</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;" dest="5+">
+ <expression>&lt;b&gt;Classification:&lt;/b&gt; ([^(]*) \(</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;certification&gt;\1&lt;/certification&gt;" dest="5+">
+ <expression repeat="yes">Classification:&lt;/b&gt;[^&gt;]*alt=&quot;([0-9]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;tagline&gt;\1&lt;/tagline&gt;" dest="5+">
+ <expression>&lt;h5&gt;Tagline:&lt;/h5&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression trim="1">Run Time:&lt;/b&gt;[^0-9]*([^&lt;]*)&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1.\2&lt;/rating&gt;&lt;votes&gt;\3&lt;/votes&gt;" dest="5+">
+ <expression noclean="1">Average Customer Review&lt;/b&gt;[^_]*stars-([0-9])-([0-9])[^)]*&gt;([0-9]*) customer reviews&lt;/a&gt;\)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes">&quot;/Sections/Genres/[^/]*/&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="5+">
+ <expression>Studio:&lt;/b&gt; ([^&lt;]*)&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;outline&gt;\2&lt;/outline&gt;&lt;plot&gt;\2&lt;/plot&gt;" dest="5+">
+ <expression trim="1">Plot (Outline|Summary):&lt;/h5&gt;([^&lt;]*)</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>&lt;b&gt;Amazon.co.uk Review&lt;/b&gt;&lt;br /&gt;\n ([^\n]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>&lt;b&gt;Synopsis&lt;/b&gt;&lt;br /&gt;\n ([^\n]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;\101.L.jpg&lt;/thumb&gt;" dest="5+">
+ <expression noclean="1">&quot;original_image&quot;, &quot;([^&quot;]*)AA2[0-9]0_\.jpg&quot;</expression>
+ </RegExp>
+
+ <RegExp input="$$9" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;b&gt;Writers:&lt;/b&gt; ([^\n]*&lt;/a&gt;)</expression>
+ </RegExp>
+ <expression noclean="1" repeat="yes">[^&gt;]*&gt;([^&lt;]+)&lt;/a&gt;</expression>
+ </RegExp>
+
+ <RegExp input="$$9" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;b&gt;Directors:&lt;/b&gt; ([^\n]*&lt;/a&gt;)</expression>
+ </RegExp>
+ <expression noclean="1" repeat="yes">[^&gt;]*&gt;([^&lt;]+)&lt;/a&gt;</expression>
+ </RegExp>
+
+ <RegExp input="$$9" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;b&gt;Actors:&lt;/b&gt; ([^\n]*&lt;/a&gt;)</expression>
+ </RegExp>
+ <expression noclean="1" repeat="yes">[^&gt;]*&gt;([^&lt;]+)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+</scraper>
diff --git a/system/scrapers/video/amazonus.png b/system/scrapers/video/amazonus.png
new file mode 100644
index 0000000000..6a3f929d82
--- /dev/null
+++ b/system/scrapers/video/amazonus.png
Binary files differ
diff --git a/system/scrapers/video/amazonus.xml b/system/scrapers/video/amazonus.xml
new file mode 100644
index 0000000000..5a7e3a44eb
--- /dev/null
+++ b/system/scrapers/video/amazonus.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Initial basic version doing Studio and Thumb believed to have been written by C-Quel -->
+<!-- Then updated by John Lockwood to scrape Title, Year, MPAA, Runtime, Rating, Votes, Plot, Actors, Directors -->
+<!-- This version 1.1 dated 12/01/09 includes fix by C-Quel for processing results from Amazon to match recent change -->
+<!-- Version 1.1 also now supports the Writers field -->
+<scraper framework="1.0" date="2009-05-22" content="movies" name="Amazon US" thumb="amazonus.png" language="en">
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.amazon.com/s/ref=nb_ss_d_h_?url=search-alias%3Ddvd&amp;amp;field-keywords=\1&lt;/url&gt;" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url&gt;\1&lt;/url&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes" clear="yes" noclean="1">productTitle&quot;&gt;&lt;a href=&quot;([^&quot;]*)&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression clear="yes" noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails clearbuffers="no" dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression noclean="1">&lt;title&gt;[Amazon.com: ]*([^:]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression trim="1">[ \[\(]([0-9]{4})[ \]\)][^&lt;]*&lt;/span&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;top250&gt;\1&lt;/top250&gt;" dest="5+">
+ <expression>Top 250: #([0-9]*)&lt;/a&gt;</expression>
+ </RegExp>
+
+ <RegExp input="$$9" output="&lt;mpaa&gt;G&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;b&gt;Rating: &lt;/b&gt;[^_]*/(g)._</expression>
+ </RegExp>
+ <expression>(g)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;mpaa&gt;PG&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;b&gt;Rating: &lt;/b&gt;[^_]*/(pg)._</expression>
+ </RegExp>
+ <expression>(pg)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;mpaa&gt;PG-13&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;b&gt;Rating: &lt;/b&gt;[^_]*/(pg-13)._</expression>
+ </RegExp>
+ <expression>(pg-13)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;mpaa&gt;R&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;b&gt;Rating: &lt;/b&gt;[^_]*/(r)._</expression>
+ </RegExp>
+ <expression>(r)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;mpaa&gt;NC-17&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;b&gt;Rating: &lt;/b&gt;[^_]*/(nc-17)._</expression>
+ </RegExp>
+ <expression>(nc-17)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;mpaa&gt;UNRATED&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>&lt;b&gt;Rating: &lt;/b&gt;[^_]*/(unrated)._</expression>
+ </RegExp>
+ <expression>(unrated)</expression>
+ </RegExp>
+
+
+ <RegExp input="$$1" output="&lt;certification&gt;\1&lt;/certification&gt;" dest="5+">
+ <expression repeat="yes">Classification:&lt;/b&gt;[^&gt;]*alt=&quot;([0-9]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;tagline&gt;\1&lt;/tagline&gt;" dest="5+">
+ <expression>&lt;h5&gt;Tagline:&lt;/h5&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression trim="1">Run Time:&lt;/b&gt;[^0-9]*([^&lt;]*)&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1.\2&lt;/rating&gt;&lt;votes&gt;\3&lt;/votes&gt;" dest="5+">
+ <expression noclean="1">Average Customer Review&lt;/b&gt;[^_]*stars-([0-9])-([0-9])[^)]*&gt;([0-9]*) customer reviews&lt;/a&gt;\)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes">&quot;/Sections/Genres/[^/]*/&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="5+">
+ <expression>Studio:&lt;/b&gt; ([^&lt;]*)&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;outline&gt;\2&lt;/outline&gt;&lt;plot&gt;\2&lt;/plot&gt;" dest="5+">
+ <expression trim="1">Plot (Outline|Summary):&lt;/h5&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression trim="1">&lt;b&gt;Product Description&lt;/b&gt;&lt;br /[^&gt;]*&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;\101.L.jpg&lt;/thumb&gt;" dest="5+">
+ <expression noclean="1">&quot;original_image&quot;, &quot;([^&quot;]*)AA2[0-9]0_\.jpg&quot;</expression>
+ </RegExp>
+
+
+ <RegExp input="$$9" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;b&gt;Writers:&lt;/b&gt; ([^\n]*&lt;/a&gt;)</expression>
+ </RegExp>
+ <expression noclean="1" repeat="yes">[^&gt;]*&gt;([^&lt;]+)&lt;/a&gt;</expression>
+ </RegExp>
+
+
+ <RegExp input="$$9" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;b&gt;Directors:&lt;/b&gt; ([^\n]*&lt;/a&gt;)</expression>
+ </RegExp>
+ <expression noclean="1" repeat="yes">[^&gt;]*&gt;([^&lt;]+)&lt;/a&gt;</expression>
+ </RegExp>
+
+
+ <RegExp input="$$9" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;b&gt;Actors:&lt;/b&gt; ([^\n]*&lt;/a&gt;)</expression>
+ </RegExp>
+ <expression noclean="1" repeat="yes">[^&gt;]*&gt;([^&lt;]+)&lt;/a&gt;</expression>
+ </RegExp>
+
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+</scraper>
diff --git a/system/scrapers/video/asiandb.gif b/system/scrapers/video/asiandb.gif
new file mode 100644
index 0000000000..8ab7b9f271
--- /dev/null
+++ b/system/scrapers/video/asiandb.gif
Binary files differ
diff --git a/system/scrapers/video/asiandb.xml b/system/scrapers/video/asiandb.xml
new file mode 100644
index 0000000000..a717a2e02c
--- /dev/null
+++ b/system/scrapers/video/asiandb.xml
@@ -0,0 +1,103 @@
+<scraper framework="1.0" date="2009-05-22" name="AsianDB" content="movies" thumb="asiandb.gif" language="en">
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.asiandb.com/browse/movie_detail.pfm?code=\1&lt;url&gt;" dest="3">
+ <expression noclean="1">asiandb.com/browse/movie_detail.pfm?code=([0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url spoof=&quot;http://www.asiandb.com/browse/advanced.pfm&quot; post=&quot;true&quot;&gt;http://www.asiandb.com/browse/advanced.pfm?text=\1&amp;amp;x=0&amp;amp;y=0&amp;amp;part=movie&lt;/url&gt;" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+
+<GetSearchResults dest="3">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url&gt;http://www.asiandb.com/browse/movie_detail.pfm?code=\1&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes">&lt;a href=/browse/movie_detail.pfm\?code=([0-9]+)&gt;&lt;font class=e3b&gt;(.[^&lt;]*)&lt;/font&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+</GetSearchResults>
+
+<GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+
+<!--Title -->
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression trim="1" noclean="1">&lt;td valign=top&gt;&lt;font class=e5b&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+
+<!--Original Title
+ <RegExp input="$$1" output="&lt;originaltitle&gt;\1&lt;/originaltitle&gt;" dest="5">
+ <expression>Titolo originale.[^z]*ze=&quot;2&quot;&gt;([^)&lt;]*)</expression>
+ </RegExp> -->
+
+<!--Year Film-->
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>&lt;font class=e3&gt;\(([0-9]+)\)</expression>
+ </RegExp>
+
+<!--Director-->
+ <RegExp input="$$7" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression trim="1" noclean="1">&lt;font class=h0b color=white&gt;Crew&lt;/font&gt;(.*)</expression>
+ </RegExp>
+ <expression repeat="yes">&lt;b&gt;Director: &lt;/b[^\n]*&gt;([A-Za-z][^&lt;]*)&lt;</expression>
+ </RegExp>
+
+<!--Runtime Film-->
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression>&lt;b&gt;Runtime:&lt;/b&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+
+<!--Thumbnail -->
+ <RegExp input="$$1" output="&lt;thumb&gt;http://www.asiandb.com\1&lt;/thumb&gt;" dest="5+">
+ <expression noclean="1">(/data/title/mini/[^&quot; ]*)</expression>
+ </RegExp>
+
+<!--User rating-->
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="5+">
+ <expression>&gt;Users&lt;/td&gt;.*img src=/images/rate/[0-9]+.gif&gt;\(([0-9]+)/10\)</expression>
+ </RegExp>
+
+<!--Vote count-->
+ <RegExp input="$$1" output="&lt;votes&gt;\1&lt;/votes&gt;" dest="5+">
+ <expression>&lt;font class=e2&gt;&amp;nbsp;\[([0-9]+)\]&amp;nbsp;&amp;nbsp;&lt;/font&gt;</expression>
+ </RegExp>
+
+<!--Genre Film-->
+ <RegExp input="$$7" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression trim="1" noclean="1">&lt;b&gt;Genre:(.*)&lt;b&gt;Production:</expression>
+ </RegExp>
+ <expression repeat="yes">/browse/search.pfm\?mode=genre&amp;query=[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+
+<!--Actors -->
+ <RegExp input="$$7" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression trim="1" noclean="1">&lt;b&gt;Starring&lt;/b&gt;:(.*)&lt;b&gt;Director:&lt;/b&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">&quot;&gt;([^&lt;]+)&lt;/a&gt;</expression>
+ </RegExp>
+
+
+<!--Writer-->
+ <RegExp input="$$7" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression trim="1" noclean="1">&lt;font class=h0b color=white&gt;Crew&lt;/font&gt;(.*)</expression>
+ </RegExp>
+ <expression repeat="yes">&lt;b&gt;Writer: &lt;/b[^\n]*&gt;([A-Za-z][^&lt;]*)&lt;</expression>
+ </RegExp>
+<!--Plot -->
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression trim="1">Synopsis&lt;/td&gt;&lt;/table&gt;&lt;div[^&gt;]*&gt;&lt;table[^&gt;]*&gt;&lt;td[^&gt;]*&gt;&lt;img[^&gt;]*&gt;(.*)&lt;/td&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression trim="1">Introduction&lt;/td&gt;&lt;/table&gt;&lt;div[^&gt;]*&gt;&lt;table[^&gt;]*&gt;&lt;td[^&gt;]*&gt;&lt;img[^&gt;]*&gt;(.*)&lt;/td&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;</expression>
+ </RegExp>
+
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+</scraper>
diff --git a/system/scrapers/video/cinefacts.png b/system/scrapers/video/cinefacts.png
new file mode 100644
index 0000000000..6831e28f30
--- /dev/null
+++ b/system/scrapers/video/cinefacts.png
Binary files differ
diff --git a/system/scrapers/video/cinefacts.xml b/system/scrapers/video/cinefacts.xml
new file mode 100644
index 0000000000..0af556e415
--- /dev/null
+++ b/system/scrapers/video/cinefacts.xml
@@ -0,0 +1,134 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="yes"?>
+<scraper framework="1.1" date="2009-07-28" name="Cinefacts.de" content="movies" thumb="cinefacts.png" language="de">
+ <include>common/tmdb.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Fanart&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+
+ <CreateSearchUrl dest="3" SearchStringEncoding="iso-8859-1">
+ <RegExp input="$$1" output="http://www.cinefacts.de/suche/suche.php?name=\1" dest="3">
+ <expression noclean="1"/>
+ </RegExp>
+ </CreateSearchUrl>
+
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\3 (\4)&lt;/title&gt;&lt;url cache=&quot;film.xml&quot; &gt;http://www.cinefacts.de/kino/\1/\2/filmdetails.html&lt;/url&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes">&gt;&lt;a href=&quot;/kino/([0-9]*)/(.[^\/]*)/filmdetails.html&quot;&gt;[^&lt;]*&lt;b title=&quot;([^&quot;]*)&quot; class=&quot;headline&quot;&gt;[^&lt;]+&lt;/b&gt;&lt;/a&gt;&lt;br&gt;[^&lt;]+&lt;br&gt;+[^0-9]+([^&lt;]*)</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetSearchResults>
+
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <!--Title-->
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5+">
+ <expression trim="1" noclean="1">&lt;h1&gt;([^&lt;]*)</expression>
+ </RegExp>
+
+ <!--Original Title-->
+ <RegExp input="$$1" output="&lt;originaltitle&gt;\1&lt;/originaltitle&gt;" dest="5+">
+ <expression>&lt;dt class=&quot;c1&quot;&gt;Originaltitel:&lt;/dt&gt;[^&lt;]*&lt;dd class=&quot;first&quot;&gt;(.[^&lt;]*)&lt;/dd&gt;</expression>
+ </RegExp>
+
+ <!--Genre-->
+ <RegExp input="$$1" output="\1" dest="4+">
+ <expression noclean="1">Genre:([^:]*)Deutschlandstart:</expression>
+ </RegExp>
+ <RegExp input="$$4" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes" noclean="1" trim="1">&gt;*[ A-Za-z]([^&lt;&gt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+
+ <!--Director Film-->
+ <RegExp input="$$1" output="\1" dest="7+">
+ <expression noclean="1">Regie:([^:]*)Buch:</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <expression repeat="yes" >&lt;a href=&quot;[^&quot;]*&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+
+ <!--Actors-->
+ <RegExp input="$$1" output="\1" dest="7+">
+ <expression noclean="1">Darsteller:&lt;/td&gt;(.*)&lt;/table</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\2&lt;/role&gt;&lt;/actor&gt;" dest="5+">
+ <expression repeat="yes">&gt;([^&lt;&gt;]*)&lt;/a&gt;&lt;/td&gt;+[^&lt;]+&lt;[^&gt;]+&gt; als([ A-Za-z]*)</expression>
+ </RegExp>
+
+ <!--Studio-->
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="5+">
+ <expression>Studio:([^\.]*)\.</expression>
+ </RegExp>
+
+ <!--Year-->
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>&lt;/a&gt; ([0-9]*) &lt;/dd&gt;</expression>
+ </RegExp>
+
+ <!--MPAA-->
+ <RegExp input="$$1" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;" dest="5+">
+ <expression>FSK:&lt;/dt&gt;[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+
+ <!--Runtime-->
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression>L.nge:&lt;/dt&gt;[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+
+ <!--Plot-->
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>KURZINHALT&lt;/h2&gt;&lt;/li&gt;[^&gt;]*&gt;*([^&lt;]*)[&lt;/li&gt;]</expression>
+ </RegExp>
+
+ <!--Writers-->
+ <RegExp input="$$1" output="\1" dest="6+">
+ <expression noclean="1">Buch:([^:]*)Musik:</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="5+">
+ <expression repeat="yes" >&lt;a href=&quot;[^&quot;]*&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+
+ <!--Poster URL-->
+ <RegExp input="$$1" output="&lt;url function=&quot;GetThumbnailLink&quot;&gt;http://www.cinefacts.de/kino/film/\1/\2/plakate.html&lt;/url&gt;" dest="5+">
+ <expression repeat ="yes">&lt;a href=&quot;/kino/film/([0-9]*)/([^\/]*)/plakate.html&quot;&gt;</expression>
+ </RegExp>
+
+ <!--IMDB URL-->
+ <RegExp conditional="fanart" input="$$8" output="&lt;url function=&quot;GetTMDBFanartByIMDBId&quot;&gt;http://www.google.com/search?q=site:imdb.com\1&lt;/url&gt;" dest="5+">
+ <RegExp input="$$1" output="&quot;\2&quot;+\1+||+&quot;\2&quot;" dest="7">
+ <expression>&lt;h1&gt;[^&lt;]*&lt;/h1&gt;[^0-9]*([0-9]*) &lt;/li&gt;[^:]*:&lt;/dt&gt;[^&lt;]*&lt;dd class=&quot;first&quot;&gt;(.[^&lt;]*)&lt;/dd&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="+\1" dest="8+">
+ <expression repeat="yes">([^ ,]+)</expression>
+ </RegExp>
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetDetails>
+
+ <!--Thumbnail-->
+ <GetThumbnailLink dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5+">
+ <RegExp input="$$1" output="&lt;url function=&quot;GetThumbnail&quot;&gt;http://www.cinefacts.de/kino/film/\1&lt;/url&gt;" dest="2+">
+ <expression repeat="yes" noclean="1">&lt;a href=&quot;/kino/film/([^&quot;]+)&quot;&gt;[^&lt;]*&lt;img</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetThumbnailLink>
+
+ <GetThumbnail dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb&gt;http://www.cinefacts.de/kino/plakat/\1&lt;/thumb&gt;" dest="2+">
+ <expression>src=&quot;/kino/plakat/([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetThumbnail>
+</scraper>
diff --git a/system/scrapers/video/common/dtrailer.xml b/system/scrapers/video/common/dtrailer.xml
new file mode 100644
index 0000000000..98ded043dc
--- /dev/null
+++ b/system/scrapers/video/common/dtrailer.xml
@@ -0,0 +1,15 @@
+<scraperfunctions>
+ <GetDTrailerLink dest="3">
+ <RegExp input="$$5" dest="3" output="&lt;details&gt;\1&lt;/details&gt;">
+ <RegExp input="$$1" dest="5" output="&lt;url function=&quot;GetDTrailer&quot;&gt;http://en.dtrailer.com/movies/watch/\1&lt;/url&gt;">
+ <expression>&lt;a href=&quot;http://en.dtrailer.com/movies/watch/(/?[^\&gt;]+)&quot; class=&quot;thumb&quot; title=&quot;(/?[^\&gt;]+)&quot;&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDTrailerLink>
+ <GetDTrailer dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;trailer&gt;http://www.dtrailer.com/dupload/trailerz/\1.flv&lt;/trailer&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1">s1\.addVariable\(&quot;file&quot;,&quot;(/?[^\&gt;]+).flv&quot;\);</expression>
+ </RegExp>
+ </GetDTrailer>
+</scraperfunctions>
diff --git a/system/scrapers/video/common/imdb.xml b/system/scrapers/video/common/imdb.xml
new file mode 100644
index 0000000000..235edc2460
--- /dev/null
+++ b/system/scrapers/video/common/imdb.xml
@@ -0,0 +1,74 @@
+<scraperfunctions>
+ <GetIMDBThumbs dest="5">
+ <RegExp input="$$6" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1_SX$INFO[imdbscale]_SY$INFO[imdbscale]_\2" dest="4">
+ <expression noclean="1,2">&lt;a name=&quot;poster&quot;.*?src=&quot;(.*?)_S.*?(.jpg)&quot;.*?&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$4" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="6">
+ <expression noclean="1">(.*?_SX[0-9]+_SY[0-9]+_.jpg)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetIMDBThumbs>
+ <GetIMDBTrailer dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;&lt;trailer urlencoded=&quot;yes&quot;&gt;\1&lt;/trailer&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="2">
+ <expression noclean="1">&quot;file&quot;[^&quot;]*&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="$$2/\1" dest="2">
+ <expression noclean="1">&quot;id&quot;[^&quot;]*&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetIMDBTrailer>
+ <GetIMDBWriters dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp conditional="!fullcredits" input="$$1" output="\1" dest="6">
+ <expression noclean="1">&gt;Writer.*?:&lt;/h5&gt;(.*?)&lt;/div&gt;</expression>
+ </RegExp>
+ <RegExp conditional="fullcredits" input="$$1" output="\1" dest="6">
+ <expression noclean="1">Writing credits(.*?)name=&quot;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="2+">
+ <expression repeat="yes">&lt;a href=&quot;/name/[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetIMDBWriters>
+ <GetIMDBCast dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">&lt;table class=&quot;cast&quot;&gt;(.*?)&lt;/table&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;thumb&gt;\1_SX$INFO[imdbscale]_SY$INFO[imdbscale]_\2&lt;/thumb&gt;&lt;name&gt;\3&lt;/name&gt;&lt;role&gt;\4&lt;/role&gt;&lt;/actor&gt;" dest="7">
+ <expression clear="yes" repeat="yes" noclean="1,2" trim="3,4">&lt;img src=&quot;(?:([^&quot;]*\.)[^&quot;]*(\.jpg))?[^&gt;]*[^&quot;]*&quot;nm&quot;&gt;&lt;a href=&quot;[^&quot;]*[^&gt;]*&gt;([^&lt;]*)&lt;[^&quot;]*&quot;ddd&quot;&gt; ... [^&quot;]*&quot;char&quot;&gt;(.*?)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;actor&gt;&lt;thumb&gt;\1&lt;/thumb&gt;\2&lt;/actor&gt;" dest="2+">
+ <expression clear="yes" repeat="yes" noclean="1,2,3">&lt;actor&gt;&lt;thumb&gt;(?:(http.*?)|_SX[0-9]+_SY[0-9]+_)&lt;/thumb&gt;(.*?)&lt;/actor&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetIMDBCast>
+ <GetIMDBDirectors dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp conditional="!fullcredits" input="$$1" output="\1" dest="6">
+ <expression clear="yes" noclean="1">&gt;Director.*?&lt;/h5&gt;(.*?)&lt;/div&gt;</expression>
+ </RegExp>
+ <RegExp conditional="fullcredits" input="$$1" output="\1" dest="6">
+ <expression clear="yes" noclean="1">Directed by(.*?)name=&quot;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;director&gt;\1&lt;/director&gt;" dest="2+">
+ <expression clear="yes" repeat="yes">&lt;a href=&quot;/name/[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetIMDBDirectors>
+ <GetIMDBPlot dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="2">
+ <expression clear="yes">&lt;p class="plotpar"&gt;\n([^\n]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetIMDBPlot>
+</scraperfunctions>
diff --git a/system/scrapers/video/common/impa.xml b/system/scrapers/video/common/impa.xml
new file mode 100644
index 0000000000..546bc8bb7e
--- /dev/null
+++ b/system/scrapers/video/common/impa.xml
@@ -0,0 +1,24 @@
+<scraperfunctions>
+ <GetIMPALink dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;GetIMPAThumbs&quot;&gt;http://\1impawards.com/\2&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1,2">http://([^&quot;]*)impawards.com/([^&quot;]*)&quot;&gt;</expression>
+ </RegExp>
+ </GetIMPALink>
+ <GetIMPAThumbs dest="6">
+ <RegExp input="$$4" output="&lt;details&gt;\1&lt;/details&gt;" dest="6">
+ <RegExp input="$$1" output="&lt;url function=&quot;GetIMPAThumbs&quot;&gt;http://www.impawards.com/\1&lt;/url&gt;" dest="4">
+ <expression noclean="1">&lt;meta http-equiv=&quot;REFRESH&quot; content=&quot;0;URL=[^/]*/([^&quot;]*)&quot;&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression noclean="1">value=&quot;/([0-9]*)/[^&quot;]*\.html&quot;&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;http://www.impawards.com/$$8/posters/\2&lt;/thumb&gt;" dest="4+">
+ <expression noclean="1">&lt;img (SRC|src)=&quot;posters/([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;http://www.impawards.com/$$8/posters/\1&lt;/thumb&gt;" dest="4+">
+ <expression repeat="yes" noclean="1">thumbs/imp_([^&gt;]*ver[^&gt;]*.jpg)&gt;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetIMPAThumbs>
+</scraperfunctions>
diff --git a/system/scrapers/video/common/movieposterdb.xml b/system/scrapers/video/common/movieposterdb.xml
new file mode 100644
index 0000000000..41386c495b
--- /dev/null
+++ b/system/scrapers/video/common/movieposterdb.xml
@@ -0,0 +1,15 @@
+<scraperfunctions>
+ <GetMoviePosterDBLink dest="6">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;GetMoviePosterDBThumbs&quot;&gt;\1&lt;/url&gt;&lt;/details&gt;" dest="6">
+ <expression>(http://www.movieposterdb.com/movie/[^&quot;]*)&quot;</expression>
+ </RegExp>
+ </GetMoviePosterDBLink>
+ <GetMoviePosterDBThumbs dest="5">
+ <RegExp input="$$6" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb&gt;\1l_\2&lt;/thumb&gt;" dest="6">
+ <expression repeat="yes" noclean="1,2">class=&quot;poster&quot;.*?src=&quot;(.*?)[a-z]_(.*?)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetMoviePosterDBThumbs>
+</scraperfunctions>
diff --git a/system/scrapers/video/common/tmdb.xml b/system/scrapers/video/common/tmdb.xml
new file mode 100644
index 0000000000..147807d25f
--- /dev/null
+++ b/system/scrapers/video/common/tmdb.xml
@@ -0,0 +1,40 @@
+<scraperfunctions>
+ <GetTMDBFanartByIMDBId dest="4">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="&lt;url function=&quot;GetTMDBFanart&quot; cache=&quot;tmdb-\1.xml&quot;&gt;http://api.themoviedb.org/2.0/Movie.getInfo?id=\1&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="5">
+ <expression>&lt;id&gt;([0-9]*)&lt;/id&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetTMDBFanartByIMDBId&quot; cache=&quot;tmdb-trans-\1.xml&quot; &gt;http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=\1&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="5">
+ <expression>/title/([t0-9]*)</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetTMDBFanartByIMDBId>
+ <GetTMDBFanart dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;&lt;fanart url=&quot;http://themoviedb.org/image/backdrops&quot;&gt;\1&lt;/fanart&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb preview=&quot;/\1/\2_poster.\3&quot;&gt;/\1/\2.\3&lt;/thumb&gt;" dest="2">
+ <expression repeat="yes">&lt;backdrop size=&quot;original&quot;&gt;.*?/([0-9]+)/([^\.]+)\.([^&lt;]*)&lt;/backdrop&gt;</expression>
+ </RegExp>
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
+ </GetTMDBFanart>
+ <GetTMDBThumbsByIMDBId dest="4">>
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="&lt;url function=&quot;GetTMDBThumbs&quot; cache=&quot;tmdb-\1.xml&quot;&gt;http://api.themoviedb.org/2.0/Movie.getInfo?id=\1&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="5">
+ <expression>&lt;id&gt;([0-9]*)&lt;/id&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetTMDBThumbsByIMDBId&quot; cache=&quot;tmdb-trans-\1.xml&quot;&gt;http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=\1&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="5">
+ <expression>/title/([t0-9]*)</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetTMDBThumbsByIMDBId>
+ <GetTMDBThumbs dest="5">
+ <RegExp input="$$4" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb preview=&quot;\1_mid.\2&quot;&gt;\1.\2&lt;/thumb&gt;" dest="4">
+ <expression repeat="yes">&lt;poster size=&quot;original&quot;&gt;([^\.]*)\.([^&lt;]*)&lt;/poster&gt;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetTMDBThumbs>
+</scraperfunctions>
diff --git a/system/scrapers/video/culturalia.gif b/system/scrapers/video/culturalia.gif
new file mode 100644
index 0000000000..6b2030bf23
--- /dev/null
+++ b/system/scrapers/video/culturalia.gif
Binary files differ
diff --git a/system/scrapers/video/culturalia.xml b/system/scrapers/video/culturalia.xml
new file mode 100644
index 0000000000..33886f0eb6
--- /dev/null
+++ b/system/scrapers/video/culturalia.xml
@@ -0,0 +1,115 @@
+п»ї<scraper framework="1.0" date="2009-05-22" name="Culturalia.es" content="movies" thumb="culturalia.gif" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" language="es">
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="http://www.culturalianet.com/art/ver.php?art=\1" dest="3">
+ <expression noclean="1">art/ver\.php\?art=([0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="http://www.culturalianet.com/bus/resu.php?texto=\1&amp;donde=1" dest="3">
+ <expression noclean="1"/>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;&apos;\2&apos; de \3 (\4)&lt;/title&gt;&lt;url&gt;http://www.culturalianet.com/art/ver.php?art=\1&lt;/url&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes">&lt;a href=&apos;../art/ver.php\?art=([0-9]*)&apos; target=&apos;_top&apos;&gt;(.[^&lt;]*)\.&lt;/a&gt;.[^\(]*\. De (.[^\(]*) \(([0-9]*)\)</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <!-- Titulos y aГ±o de producciГіn !-->
+ <RegExp input="$$1" output="&lt;title&gt;\1 (\3)&lt;/title&gt;&lt;originaltitle&gt;\3&lt;/originaltitle&gt;&lt;year&gt;\2&lt;/year&gt;" dest="5">
+ <expression trim="1" noclean="1">&apos;titulo2&apos;&gt;(.[^\&lt;]*)\. \(([0-9]*)\)&lt;/font&gt;&lt;/u&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;(.[^&lt;]*)&lt;/i&gt;</expression>
+ </RegExp>
+ <!-- DIRECTOR !-->
+ <RegExp input="$$1" output="\1" dest="7">
+ <!-- Ponemos la cadena de Directores (sin limpiar en $$7) !-->
+ <expression noclean="1">Director:&lt;/font&gt;([^:]*)&lt;br&gt;&lt;br&gt;&lt;font class = &apos;titulo3&apos;&gt;</expression>
+ </RegExp>
+ <!-- Ahora hay que extraer cada director ke pueden estar en 2 formatos
+ <br><a ref=url>Nombre</a> (Cuando tienen ficha de datos)
+ <br>Nombre</br> (Cuando no tienen ficha de datos)
+ La forma que se me ocurre es extraer en 2 pasadas distintas dejando un formato comun
+ Esto reordenarГЎ los directores en la ficha. !-->
+ <RegExp input="$$6" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <RegExp input="$$7" output=" /JUR\1/JAR" dest="6">
+ <expression repeat="yes">&lt;br&gt;&lt;a href=[^0-9]*[0-9]*&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output=" /JUR\1/JAR" dest="6+">
+ <expression repeat="yes">&lt;br&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <expression repeat="yes">/JUR([^/]*)/JAR</expression>
+ </RegExp>
+ <!-- GUION - CREDITS !-->
+ <RegExp input="$$1" output="\1" dest="7">
+ <!-- Ponemos la cadena de Directores (sin limpiar en $$7) !-->
+ <expression noclean="1">Gui.n:&lt;/font&gt;([^:]*)&lt;br&gt;&lt;br&gt;&lt;font class = &apos;titulo3&apos;&gt;</expression>
+ </RegExp>
+ <!-- Ahora hay que extraer cada nombre ke pueden estar en 2 formatos
+ <br><a ref=url>Nombre</a> (Cuando tienen ficha de datos)
+ <br>Nombre</br> (Cuando no tienen ficha de datos)
+ La forma que se me ocurre es extraer en 2 pasadas distintas dejando un formato comun
+ Esto reordenarГЎ los nombres en la ficha. !-->
+ <RegExp input="$$6" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="5+">
+ <RegExp input="$$7" output=" /JUR\1/JAR" dest="6">
+ <expression repeat="yes">&lt;br&gt;&lt;a href=[^0-9]*[0-9]*&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output=" /JUR\1/JAR" dest="6+">
+ <expression repeat="yes">&lt;br&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <expression repeat="yes">/JUR([^/]*)/JAR</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>Sinopsis:&lt;/b&gt;[ ]*&lt;br&gt;([^=]*)&lt;br&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;" dest="5+">
+ <expression>moral:&lt;/font&gt; ([^&lt;]*)&lt;br&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression>Duraci.n:&lt;/font&gt; ([^&lt;]*)\.&lt;br&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\2&lt;/rating&gt;&lt;votes&gt;\1&lt;/votes&gt;" dest="5+">
+ <expression>tulo3&apos;&gt;([0-9]*)&lt;/font&gt; votos. Puntuaci.n: &lt;font class = &apos;titulo3&apos;&gt;([^&lt;]*)&lt;/font&gt; / ([^&lt;]*)\.&lt;/a&gt;</expression>
+ </RegExp>
+ <!-- GENEROS - GENRES !-->
+ <RegExp input="$$1" output="\1 /" dest="7">
+ <expression>nero:&lt;/font&gt;&lt;br&gt;([^&lt;]*)&lt;br&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <RegExp input="$$7" output=" / \1" dest="6">
+ <expression repeat="yes">([^/]*) /</expression>
+ </RegExp>
+ <expression> / (.*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="http://www.culturalianet.com/imatges/articulos/\1-1.jpg" dest="7">
+ <expression>imatges/articulos/([0-9]*)-</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <!-- ACTORES !-->
+ <RegExp input="$$1" output="\1" dest="7">
+ <!-- Ponemos la cadena de actores (sin limpiar en $$7) !-->
+ <expression noclean="1">Actores:&lt;/font&gt;([^:]*)&lt;br&gt;&lt;br&gt;&lt;font class = &apos;titulo3&apos;&gt;</expression>
+ </RegExp>
+ <!-- Ahora hay que extraer cada actor ke pueden estar en 2 formatos
+ <br><a ref=url>Nombre Actor</a> (Cuando tienen ficha de datos)
+ <br>Nombre actor</br> (Cuando no tienen ficha de datos)
+ La forma que se me ocurre es extraer en 2 pasadas distintas dejando un formato comun
+ Esto reordenarГЎ los actores en la ficha. Pero no me parece mal puesto que pondra primero
+ los actores con ficha (los mas importantes, no?) !-->
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;" dest="5+">
+ <RegExp input="$$7" output=" /JUR\1/JAR" dest="6">
+ <expression repeat="yes">&lt;br&gt;&lt;a href=[^0-9]*[0-9]*&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output=" /JUR\1/JAR" dest="6+">
+ <expression repeat="yes">&lt;br&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <expression repeat="yes">/JUR([^/]*)/JAR</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetDetails>
+</scraper>
diff --git a/system/scrapers/video/daum.png b/system/scrapers/video/daum.png
new file mode 100644
index 0000000000..63855ec0c7
--- /dev/null
+++ b/system/scrapers/video/daum.png
Binary files differ
diff --git a/system/scrapers/video/daum.xml b/system/scrapers/video/daum.xml
new file mode 100644
index 0000000000..6b63f6c997
--- /dev/null
+++ b/system/scrapers/video/daum.xml
@@ -0,0 +1,183 @@
+п»ї<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.1" date="2009-08-08" name="DAUM (Korean)" content="movies" thumb="daum.png" language="ko">
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;нЏ¬мЉ¤н„°&quot; type=&quot;bool&quot; id=&quot;EnableThumbs&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;팬아트(고화질)&quot; type=&quot;bool&quot; id=&quot;EnableFanArt&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;к·№мћ‘к°Ђ&quot; type=&quot;bool&quot; id=&quot;EnableWriter&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://movie.daum.net/moviedetail/moviedetailMain.do?movieId=\1&lt;/url&gt;" dest="3">
+ <expression>movie\.daum\.net[^\?]*\?movieId=([0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateSearchUrl dest="3" SearchStringEncoding="UTF-8">
+ <RegExp input="$$1" output="http://movie.daum.net/search.do?type=movie&amp;q=\1" dest="3">
+ <expression noclean="1"/>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2(\4,\3) &lt;/title&gt;&lt;url&gt;http://movie.daum.net/moviedetail/moviedetailMain.do?movieId=\1&lt;/url&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes">class=&quot;fl srch&quot;&gt;&lt;a href=&quot;http://movie.daum.net/moviedetail/moviedetailMain.do\?movieId=([0-9]*)&quot;[^&gt;]*&gt;(.[^\(]*)\(([0-9]*)\)[^\%]*\%&quot;[^&quot;]*&quot;cb&quot;[^&quot;]*&quot;fs13[^&quot;]*&quot;&gt;(.[^\/]*)\/</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails dest="3">
+ <RegExp input="$$8" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <!-- Titles, year !-->
+ <RegExp input="$$1" output="&lt;title&gt;\1 (\3)&lt;/title&gt;&lt;year&gt;\2&lt;/year&gt;" dest="8">
+ <expression noclean="1">class=&quot;title_kor&quot;&gt;&lt;a[^&gt;]*&gt;(.[^&lt;]*)&lt;/a&gt;&lt;/strong&gt;[^&gt;]*&gt;\(&lt;a[^&gt;]*&gt;([0-9]*)&lt;/a&gt;\)[^&quot;]*&quot;title_AKA&quot;[^&quot;]*&quot;eng&quot;&gt;(.[^&lt;]*)&lt;</expression>
+ </RegExp>
+ <!-- Director's names !-->
+ <RegExp input="$$7" output="&lt;director&gt;\1&lt;/director&gt;" dest="8+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">&lt;strong&gt;к°ђлЏ…&lt;/strong&gt;(.*)&lt;strong&gt;л“±кё‰&lt;/strong&gt;</expression>
+ </RegExp>
+ <expression noclean="1" repeat="yes">&lt;a[^&gt;]*&gt;(.[^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <!-- Actors !-->
+ <RegExp input="$$7" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\2&lt;/role&gt;&lt;thumb&gt;\3&lt;/thumb&gt;&lt;/actor&gt;" dest="8+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">&quot;div_actors&quot;(.*)&quot;netizenGrade&quot;</expression>
+ </RegExp>
+ <expression noclean="1" repeat="yes">class=&quot;actor&quot; title=&quot;(.[^\|]*)\|\|(.[^&quot;]*)&quot;&gt;&lt;img src=&quot;(.[^&quot;]*)&quot;</expression>
+ </RegExp>
+ <!-- Tag Line !-->
+ <RegExp input="$$7" output="&lt;tagline&gt;\1&lt;/tagline&gt;" dest="8+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">&quot;synopsis&quot;(.*)id=&quot;review&quot;</expression>
+ </RegExp>
+ <expression>class=&quot;txt&quot;&gt;[^&gt;]*&gt;(.[^&lt;]*)&lt;/b&gt;</expression>
+ </RegExp>
+ <!-- Plot !-->
+ <RegExp input="$$7" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="8+">
+ <expression>class=&quot;txt&quot;&gt;[^&gt;]*&gt;[^&lt;]*&lt;/b&gt;&lt;br&gt;(.[^\t]*)\t</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="8+">
+ <expression>class=&quot;txt&quot;&gt;\n\t\t(.[^\t]*)\t</expression>
+ </RegExp>
+ <!-- Single Poster !-->
+ <RegExp conditional="!EnableThumbs" input="$$1" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="8+">
+ <expression>&lt;p class=&quot;poster&quot;&gt;&lt;a[^&lt;]*&lt;img src=&quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <!-- Premiered !-->
+ <RegExp input="$$7" output="&lt;premiered&gt;\1.\2&lt;/premiered&gt;" dest="8+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">&lt;strong&gt;мљ”м•Ѕм •ліґ&lt;/strong&gt;(.*)&lt;strong&gt;к°ђлЏ…&lt;/strong&gt;</expression>
+ </RegExp>
+ <expression noclean="1">([0-9]*)-([0-9]*)-[0-9]*</expression>
+ </RegExp>
+ <!-- Genres !-->
+ <RegExp input="$$7" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="8+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">&lt;strong&gt;мљ”м•Ѕм •ліґ&lt;/strong&gt;(.*)&lt;strong&gt;к°ђлЏ…&lt;/strong&gt;</expression>
+ </RegExp>
+ <expression noclean="1" repeat="yes">&lt;a href=&apos;[^&apos;]*&apos;&gt;(.[^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <!-- Runtime !-->
+ <RegExp input="$$7" output="&lt;runtime&gt;\1 분&lt;/runtime&gt;" dest="8+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">&lt;strong&gt;мљ”м•Ѕм •ліґ&lt;/strong&gt;(.*)&lt;strong&gt;к°ђлЏ…&lt;/strong&gt;</expression>
+ </RegExp>
+ <expression noclean="1">([0-9]*) 분</expression>
+ </RegExp>
+ <!-- User rating !-->
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="8+">
+ <expression>&quot;star_big pink&quot;&gt;&lt;[^&gt;]*&gt;&lt;[^&gt;]*&gt;[^&gt;]*&gt;[^&gt;]*&gt;&lt;em&gt;(.[^&lt;]*)&lt;/em&gt;</expression>
+ </RegExp>
+ <!-- User vote !-->
+ <RegExp input="$$1" output="&lt;votes&gt;\1&lt;/votes&gt;" dest="8+">
+ <expression>&lt;span class=&quot;fs11 fc3&quot;&gt;\(([0-9]*)лЄ… м°ём—¬\)&lt;/span&gt;</expression>
+ </RegExp>
+ <!-- MPAA !-->
+ <RegExp input="$$7" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;" dest="8+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">&lt;strong&gt;л“±кё‰&lt;/strong&gt;&lt;/dt&gt;[^&gt;]*&gt;(.[^&lt;]*)&lt;/dd&gt;</expression>
+ </RegExp>
+ <expression noclean="1" trim="1">\b(.[^\t]*)\t</expression>
+ </RegExp>
+ <!-- Poster !-->
+ <RegExp conditional="EnableThumbs" input="$$1" output="&lt;url function=&quot;GetDaumPoster&quot;&gt;\1&lt;/url&gt;" dest="8+">
+ <expression>&lt;p class=&quot;poster&quot;&gt;&lt;a href=&quot;(.[^&quot;]*)&quot;</expression>
+ </RegExp>
+
+ <!-- FanArts !-->
+ <RegExp conditional="EnableFanArt" input="$$5" output="&lt;url function=&quot;GetTMDBId&quot;&gt;http://api.themoviedb.org/2.0/Movie.search?title=\1&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="8+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1" clear="yes">&quot;title_AKA&quot;[^&quot;]*&quot;eng&quot;&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="+\1" dest="5">
+ <expression repeat="yes" clear="yes">([^ ,]+)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ <!-- FanArts !-->
+ <RegExp conditional="EnableFanArt" input="$$1" output="&lt;url function=&quot;GetDAUMFanart&quot;&gt;\1&lt;/url&gt;" dest="8+">
+ <expression noclean="1">class=&quot;title_kor&quot;&gt;&lt;a href=&quot;(.[^&quot;]*)&quot;</expression>
+ </RegExp>
+ <!-- Writer !-->
+ <RegExp conditional="EnableWriter" input="$$1" output="&lt;url function=&quot;GetWriter&quot;&gt;\1&lt;/url&gt;" dest="8+">
+ <expression noclean="1">&lt;a class=&quot;tab3&quot; href=&quot;(.[^&quot;]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetDetails>
+
+ <GetDaumPoster dest="8">
+ <RegExp input="$$9" output="&lt;details&gt;\1&lt;/details&gt;" dest="8">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">id=&quot;photo&quot;(.*)id=&quot;steal&quot;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;thumb preview=&quot;http://\1/C155x225/\2&quot;&gt;http://\1/image/\2&lt;/thumb&gt;" dest="9">
+ <expression noclean="1" repeat="yes">&lt;img src=&quot;http://(.[^/]*)/C155x225/(.[^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;thumb preview=&quot;http://movie.daum-img.net/movie/movie-photo/\1/\2/\3/155_225_\4&quot;&gt;http://movie.daum-img.net/movie/movie-photo/\1/\2/\3/\4&lt;/thumb&gt;" dest="9+">
+ <expression noclean="1" repeat="yes">&lt;img src=&quot;http://movie.daum-img.net/movie/movie-photo/([0-9]*)/([0-9]*)/([0-9]*)/[0-9]*_[0-9]*_(.[^&quot;]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDaumPoster>
+
+ <GetTMDBId dest="8">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;GetTMDBFanart&quot;&gt;http://api.themoviedb.org/2.0/Movie.getInfo?id=\1&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;&lt;/details&gt;" dest="8">
+ <expression>&lt;id&gt;([0-9]*)&lt;/id&gt;</expression>
+ </RegExp>
+ </GetTMDBId>
+
+ <GetTMDBFanart clearbuffers="no" dest="8">
+ <RegExp input="$$1" output="&lt;thumb preview=&quot;http://themoviedb.org/image/backdrops/\1/\2_poster.\3&quot;&gt;http://themoviedb.org/image/backdrops/\1/\2.\3&lt;/thumb&gt;" dest="10+">
+ <expression clear="yes" noclean="1" repeat="yes">&lt;backdrop size=&quot;original&quot;&gt;.*?/([0-9]+)/([^\.]+)\.([^&lt;]*)&lt;/backdrop&gt;</expression>
+ </RegExp>
+ </GetTMDBFanart>
+
+ <GetDAUMFanart clearbuffers="no" dest="8">
+ <RegExp input="$$10$$11" output="&lt;details&gt;&lt;fanart&gt;\1&lt;/fanart&gt;&lt;/details&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;thumb preview=&quot;http://\1/C93x70/\2&quot;&gt;http://\1/image/\2&lt;/thumb&gt;" dest="11">
+ <expression clear="yes" noclean="1" repeat="yes">imgArray\.push\(&quot;http://(.[^/]*)/C93x70/(.[^&quot;]*)&quot;\)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDAUMFanart>
+
+ <GetWriter dest="8">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">&lt;h5&gt;к°Ѓліё&lt;/h5&gt;(.*)&lt;h5&gt;촬мЃ&lt;/h5&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;details&gt;\1&lt;/details&gt;" dest="8">
+ <RegExp input="$$7" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="6">
+ <expression noclean="1" repeat="yes">class=&quot;em b&quot;&gt;(.[^&lt;]*)&lt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetWriter>
+</scraper>
diff --git a/system/scrapers/video/fdbpl.png b/system/scrapers/video/fdbpl.png
new file mode 100644
index 0000000000..54f9766cac
--- /dev/null
+++ b/system/scrapers/video/fdbpl.png
Binary files differ
diff --git a/system/scrapers/video/fdbpl.xml b/system/scrapers/video/fdbpl.xml
new file mode 100644
index 0000000000..547736237b
--- /dev/null
+++ b/system/scrapers/video/fdbpl.xml
@@ -0,0 +1,170 @@
+п»ї<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.1" date="2009-08-08" name="fdb.pl" content="movies" thumb="fdbpl.png" language="pl">
+ <include>common/tmdb.xml</include>
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.\1/title/tt\2/&lt;/url&gt;&lt;id&gt;tt\2&lt;/id&gt;" dest="3">
+ <expression clear="yes" noclean="1">(imdb.com/)Title\?([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url&gt;http://www.\1\2/&lt;/url&gt;&lt;id&gt;tt\2&lt;/id&gt;" dest="3+">
+ <expression clear="yes" noclean="1">(imdb.com/title/tt)([0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://akas.imdb.com/find?s=tt;q=\1$$4&lt;/url&gt;" dest="3">
+ <RegExp input="$$2" output="%20(\1)" dest="4">
+ <expression clear="yes">(.+)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression clear="yes">/title/([t0-9]*)/faq</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\1 (\2)&lt;/title&gt;&lt;url&gt;http://akas.imdb.com/title/$$7/&lt;/url&gt;&lt;id&gt;$$7&lt;/id&gt;&lt;/entity&gt;" dest="5">
+ <expression clear="yes" noclean="1">&lt;meta name=&quot;title&quot; content=&quot;([^&quot;]*) \(([0-9]*)\)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="4">
+ <expression noclean="1">(&gt;&lt;a href=&quot;/title.*)</expression>
+ </RegExp>
+ <RegExp input="$$4" output="&lt;entity&gt;&lt;title&gt;\2 (\3)&lt;/title&gt;&lt;url&gt;http://akas.imdb.com/title/\1/&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes" noclean="1,2">&gt;&lt;a href=&quot;/title/([t0-9]*)/[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt; *\(([0-9]*)</expression>
+ </RegExp>
+ <expression clear="yes" noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails clearbuffers="no" dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$2" output="&lt;id&gt;\1&lt;/id&gt;" dest="5">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;&lt;votes&gt;\2&lt;/votes&gt;" dest="5+">
+ <expression>&lt;b&gt;([0-9.]+)/10&lt;/b&gt;[^&lt;]*&lt;a href=&quot;ratings&quot; class=&quot;tn15more&quot;&gt;([0-9,]+) votes&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="5+">
+ <expression repeat="yes">&quot;/company/[^/]*/&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression trim="1">&lt;h5&gt;Runtime:&lt;/h5&gt;[^0-9]*([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression trim="1" noclean="1">&lt;title&gt;([^&lt;|^(]*)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="\1" dest="6">
+ <RegExp input="$$8" output="+\1" dest="9">
+ <expression repeat="yes">([^ ]+)</expression>
+ </RegExp>
+ <expression>\+(.*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression>a href=&quot;/Sections/Years/([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;url function=&quot;Getfdblink&quot;&gt;http://fdb.pl/katalog?catalog[query]=$$6&amp;amp;catalog[year_from]=$$7&amp;amp;catalog[order]=votes&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;url function=&quot;GetTMDBFanartByIMDBId&quot;&gt;http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=$$2&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+ <Getfdblink clearbuffers="no" dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="4">
+ <expression noclean="1">class=&quot;results&quot;([^~]*)class=&quot;clear&quot;</expression>
+ </RegExp>
+ <RegExp input="$$4" output="\1" dest="6">
+ <expression clear="yes" noclean="1,2">a href=&quot;([^&gt;]+)&quot;&gt;([^&lt;]+)[^(]+\(([0-9]+)</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;url function=&quot;GetDetailsfdb&quot;&gt;$$6&lt;/url&gt;" dest="2">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;url function=&quot;GetPlotfdb&quot;&gt;$$6/opisy&lt;/url&gt;" dest="2+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;url function=&quot;GetPosterfdb&quot;&gt;$$6/plakaty&lt;/url&gt;" dest="2+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </Getfdblink>
+ <GetDetailsfdb dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="2">
+ <expression trim="1">&lt;title&gt;([^//|^(]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="2+">
+ <expression>title&gt;.[^&lt;]*\(([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="2+">
+ <expression>Dystrybutor[^=]+[^&gt;]*&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">Gatunek[^=]+([^\n]*)</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="2+">
+ <expression repeat="yes">=[^&gt;]*&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">ReЕјyseria:(.*)Scenariusz:</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;director&gt;\1&lt;/director&gt;" dest="2+">
+ <expression repeat="yes">&lt;a href=&quot;[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">Scenariusz:(.*)Premiera:</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="2+">
+ <expression repeat="yes">&lt;a href=&quot;[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;mpaa&gt;od \1 lat&lt;/mpaa&gt;" dest="2+">
+ <expression>Od lat[^i]+i&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">Recenzja([^~]*)Dodatkowe informacje</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;tagline&gt;\1&lt;/tagline&gt;" dest="2+">
+ <expression>&lt;/a&gt;([^&lt;]+)&lt;/h3&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;outline&gt;\1&lt;/outline&gt;" dest="2+">
+ <expression>&lt;p&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">Obsada([^~]*)class=&quot;line&quot;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;actor&gt;&lt;thumb&gt;\1&lt;/thumb&gt;&lt;name&gt;\2&lt;/name&gt;&lt;role&gt;\3&lt;/role&gt;&lt;/actor&gt;" dest="2+">
+ <expression repeat="yes" noclean="1" trim="2,3">src=&quot;([^&quot;]+)/[^[A-Z]+([^&lt;]+)&lt;/a&gt;&lt;/td&gt;[^[A-Z]+([^&lt;]+)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetailsfdb>
+ <GetPlotfdb dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;&lt;plot&gt;\1&lt;/plot&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="4">
+ <expression noclean="1">id=&quot;resize-text&quot;&gt;[^&gt;]+&gt;([^~]*)&lt;div class=&quot;line&quot;</expression>
+ </RegExp>
+ <RegExp input="$$4" output="\1" dest="7">
+ <expression>([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$4" output=" \1" dest="7+">
+ <expression repeat="yes">&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$7" output="\1" dest="2">
+ <expression noclean="1" repeat="yes">([^\n]+)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetPlotfdb>
+ <GetPosterfdb dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="2+">
+ <expression noclean="1">&quot;gfx-poster&quot; src=&quot;([^&quot;]+)/</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="2+">
+ <expression noclean="1" repeat="yes">&quot;gfx-poster-gallery&quot; src=&quot;([^&quot;]+)/</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetPosterfdb>
+</scraper>
diff --git a/system/scrapers/video/filmaffinity.gif b/system/scrapers/video/filmaffinity.gif
new file mode 100644
index 0000000000..3ce1ecad6f
--- /dev/null
+++ b/system/scrapers/video/filmaffinity.gif
Binary files differ
diff --git a/system/scrapers/video/filmaffinity.xml b/system/scrapers/video/filmaffinity.xml
new file mode 100644
index 0000000000..fcff1db70c
--- /dev/null
+++ b/system/scrapers/video/filmaffinity.xml
@@ -0,0 +1,283 @@
+<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
+<scraper framework="1.1" date="2009-09-14" content="movies" name="FilmAffinity.es (Spanish)" thumb="filmaffinity.gif" language="es">
+ <include>common/tmdb.xml</include>
+ <include>common/movieposterdb.xml</include>
+ <include>common/impa.xml</include>
+ <include>common/imdb.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Buscar fotos de actores en IMDB (muy lento)&quot; type=&quot;bool&quot; id=&quot;SearchCastThumb&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Habilitar trailers&quot; type=&quot;bool&quot; id=&quot;EnableTrailers&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Sуlo pуster de FilmAffinity y sin FanArt (rбpido)&quot; type=&quot;bool&quot; id=&quot;OnlyFilmAffinity&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Habilitar FanArt&quot; type=&quot;bool&quot; id=&quot;EnableFanArt&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Descargar pуsters de IMPAwards&quot; type=&quot;bool&quot; id=&quot;EnableIMPAwards&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Descargar pуsters de MoviePosterDB&quot; type=&quot;bool&quot; id=&quot;movieposterdb&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Descargar pуster de IMDB&quot; type=&quot;bool&quot; id=&quot;EnableIMDBPosters&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Tamaсo del pуster de IMDB&quot; type=&quot;labelenum&quot; values=&quot;192|256|384|512|1024&quot; id=&quot;imdbscale&quot; default=&quot;512&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+
+ <NfoUrl dest="3">
+ <RegExp dest="3" input="$$1" output="&lt;url&gt;http://www.filmaffinity.com/es/film\1.html/&lt;/url&gt;">
+ <expression noclean="1">filmaffinity.com/es/film([0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+
+ <CreateSearchUrl dest="3" SearchStringEncoding="iso-8859-1">
+ <RegExp dest="3" input="$$1" output="&lt;url&gt;http://www.filmaffinity.com/es/search.php?stext=\1&amp;amp;stype=none&lt;/url&gt;">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression>&lt;img src="http://www.filmaffinity.com/imgs/movies/full/[0-9]*/([0-9]*).jpg"&gt;</expression>
+ </RegExp>
+ <RegExp dest="5" input="$$1" output="&lt;entity&gt;&lt;title&gt;\1 (\2)&lt;/title&gt;&lt;url&gt;http://www.filmaffinity.com/es/film$$7.html&lt;/url&gt;&lt;id&gt;$$7&lt;/id&gt;&lt;/entity&gt;">
+ <expression noclean="1">&lt;title&gt;([^&lt;]*)\(([0-9]*)\) - FilmAffinity</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="4">
+ <expression noclean="1">(&lt;b&gt;&lt;a href="/es/film.*)</expression>
+ </RegExp>
+ <RegExp dest="5+" input="$$1" output="&lt;entity&gt;&lt;title&gt;\2 (\3)&lt;/title&gt;&lt;url&gt;http://www.filmaffinity.com/es/film\1.html&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;">
+ <expression repeat="yes" noclean="1,2">&lt;a href="/es/film([0-9]*).html[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;[^\(]*\(([0-9]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp dest="5" input="$$1" output="&lt;title&gt;\1&lt;/title&gt;">
+ <expression trim="1" noclean="1">&lt;img src="http://www.filmaffinity.com/images/movie.gif" border="0"&gt; ([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>/ SINOPSIS: ([^=]*)\(FILMAFFINITY\)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>/ SINOPSIS: ([^=]*)FILMAFFINITY\)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>SINOPSIS LARGA: ([^=]*)\(FILMAFFINITY\)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;" dest="5+">
+ <expression>SINOPSIS CORTA: ([^=]*)FILMAFFINITY\)([^=]*)FILMAFFINITY\)([^=]*)FILMAFFINITY\)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;" dest="5+">
+ <expression>SINOPSIS CORTA: ([^=]*)FILMAFFINITY\)([^=]*)FILMAFFINITY\)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>/ [^=]* / ([^=]*)FILMAFFINITY\)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>/ ([^=]*)FILMAFFINITY\)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;b&gt;A.O&lt;/b&gt;&lt;/td&gt;(.*)&lt;b&gt;DURACI.N&lt;/b&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">&lt;td &gt;([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="5+">
+ <RegExp input="$$1" output="/ \1 /" dest="9">
+ <expression noclean="1">&lt;b&gt;PRODUCTORA&lt;/b&gt;&lt;/td&gt;[^&gt;]*&gt;([^&lt;]*)&lt;/td&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">([^/]*)/</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;b&gt;DIRECTOR&lt;/b&gt;&lt;/td&gt;(.*)&lt;b&gt;GUI.N&lt;/b&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">stext=[^&gt;]*&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;tagline&gt;\1 - " dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;b&gt;PA.S&lt;/b&gt;&lt;/td&gt;(.*)&lt;b&gt;DIRECTOR&lt;/b&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">title="([^"]+)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="\1&lt;/tagline&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;b&gt;T.TULO ORIGINAL&lt;/b&gt;&lt;/td&gt;(.*)&lt;b&gt;A.O&lt;/b&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">&lt;td &gt;&lt;b&gt;([^&lt;]+)&lt;/b&gt;&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;b&gt;GUI.N&lt;/b&gt;&lt;/td&gt;(.*)&lt;b&gt;M.SICA&lt;/b&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">&lt;td &gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1." dest="8">
+ <expression noclean="1">&lt;td valign="top"&gt;[^/]*/([^/]*) / [^=]*&lt;</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <RegExp input="$$8" output=" / \1" dest="9">
+ <expression repeat="yes">([^\.]*)\.</expression>
+ </RegExp>
+ <expression>/ (.*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1." dest="7">
+ <expression noclean="1">&lt;td valign="top"&gt;([^/]*) / [^=|^/]*&lt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <RegExp input="$$7" output=" / \1" dest="6">
+ <expression repeat="yes">([^\.]*)\.</expression>
+ </RegExp>
+ <expression>/ (.*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;" dest="5+">
+ <expression>&lt;td valign="top"&gt;([^/]*)/[^/]* / [^=]*FILMAFFINITY\)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1.\2&lt;/rating&gt;" dest="5+">
+ <expression>font-size:22px; font-weight: bold;"&gt;([0-9]+),([0-9]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;votes&gt;\1\2&lt;/votes&gt;" dest="5+">
+ <expression>&lt;tr&gt;&lt;td align="center"&gt;\(([0-9\.]+) votos\)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;runtime&gt;\1 minutos&lt;/runtime&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;b&gt;DURACI.N&lt;/b&gt;&lt;/td&gt;(.*)&lt;b&gt;PA.S&lt;/b&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">&lt;td&gt;([0-9]*) min\.</expression>
+ </RegExp>
+
+ <RegExp input="$$20" output="\1" dest="5+">
+ <RegExp conditional="!SearchCastThumb" input="$$1" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;" dest="20+">
+ <expression repeat="yes" noclean="1" trim="1">&lt;a href="search\.php.stype=cast[^&gt;]*&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp conditional="SearchCastThumb" input="$$1" output="&lt;url function=&quot;SearchCastThumb&quot;&gt;http://spanish.imdb.com/find?s=nm&amp;amp;q=\1&lt;/url&gt;" dest="20+">
+ <expression repeat="yes" noclean="1" trim="1">&lt;a href="search\.php.stype=cast.stext=([^&quot;]*)[^&gt;]*&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="" dest="20">
+ <expression>&lt;a href="search\.php.stype=cast[^&gt;]*&gt;(Animation)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <RegExp conditional="EnableTrailers" input="$$1" output="&lt;url function=&quot;SearchTrailerPage&quot;&gt;http://www.filmaffinity.com/es/evideos.php\1&lt;/url&gt;" dest="5+">
+ <expression noclean="1">&lt;a href="/es/evideos.php([^"]+)</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;thumb&gt;http://pics.filmaffinity.com/\1&lt;/thumb&gt;" dest="5+">
+ <expression noclean="1,2">href="http://pics.filmaffinity.com/([^=]*large.jpg)"</expression>
+ </RegExp>
+
+ <RegExp conditional="!OnlyFilmAffinity" input="$$1" output="&lt;url function=&quot;GetFilmAffinityPosters&quot;&gt;http://www.filmaffinity.com/es/filmimages.php?movie_id=\1&lt;/url&gt;" dest="5+">
+ <expression noclean="1,2">href="/es/filmimages.php.movie_id=([^"]+)</expression>
+ </RegExp>
+
+ <!--URL to Google and IMDB-->
+ <RegExp conditional="!OnlyFilmAffinity" input="$$9" output="&lt;url function=&quot;GoogleToIMDB&quot;&gt;http://www.google.com/search?q=site:imdb.com\1&lt;/url&gt;" dest="5+">
+ <RegExp input="$$8" output="+\1" dest="9">
+ <RegExp input="$$7" output="\1" dest="8">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">&lt;b&gt;T.TULO ORIGINAL&lt;/b&gt;&lt;/td&gt;(.*)&lt;b&gt;A.O&lt;/b&gt;</expression>
+ </RegExp>
+ <expression>&lt;td &gt;&lt;b&gt;([^&lt;]+)&lt;/b&gt;&lt;/td&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">([^ ,]+)</expression>
+ </RegExp>
+ <RegExp input="$$6" output="+\1" dest="9+">
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">&lt;b&gt;A.O&lt;/b&gt;&lt;/td&gt;(.*)&lt;b&gt;DURACI.N&lt;/b&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">&lt;td &gt;([0-9]*)</expression>
+ </RegExp>
+ <expression></expression>
+ </RegExp>
+
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+
+ <SearchCastThumb dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;&lt;/details&gt;" dest="5">
+ <expression noclean="1,9" clear="yes">IMDb Name.*?&quot;q&quot; size=&quot;28&quot; value=&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$4" output="&lt;details&gt;&lt;actor&gt;\1&lt;/actor&gt;&lt;/details&gt;" dest="5+">
+ <RegExp input="$$1" output="&lt;name&gt;\1&lt;/name&gt;" dest="4">
+ <expression trim="1" noclean="1" clear="yes">&quot;tn15title&quot;&gt;.&lt;h1&gt;([^&lt;|^(]*)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="4+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;div class=&quot;photo&quot;&gt;(.*) alt=&quot;</expression>
+ </RegExp>
+ <expression repeat="yes">img border=&quot;0&quot; src=&quot;([^=]*.jpg)</expression>
+ </RegExp>
+ <expression noclean="1">(.*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;GetCastThumb&quot;&gt;http://spanish.imdb.com\1&lt;/url&gt;&lt;/details&gt;" dest="5+">
+ <expression noclean="1">Media of.nbsp;&lt;a href=&quot;([^&quot;]*)</expression>
+ </RegExp>
+ </SearchCastThumb>
+
+ <GetCastThumb dest="5">
+ <RegExp input="$$4" output="&lt;details&gt;&lt;actor&gt;\1&lt;/actor&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;name&gt;\1&lt;/name&gt;" dest="4">
+ <expression noclean="1" clear="yes" trim="1">&lt;title&gt;([^&lt;|^(]*)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="4+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;div class=&quot;photo&quot;&gt;(.*) alt=&quot;</expression>
+ </RegExp>
+ <expression repeat="yes">img border=&quot;0&quot; src=&quot;([^=]*.jpg)</expression>
+ </RegExp>
+ <expression noclean="1" clear="yes">(.*)</expression>
+ </RegExp>
+ </GetCastThumb>
+
+ <SearchTrailerPage dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;trailer&gt;http://www.yobajo.com/watch?v=\1&lt;/trailer&gt;&lt;/details&gt;" dest="5+">
+ <expression noclean="1">http://www.youtube.com/v/([^&amp;|^\\]*)</expression>
+ </RegExp>
+ </SearchTrailerPage>
+
+ <GoogleToIMDB dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">/title/tt([0-9]*)</expression>
+ </RegExp>
+ <RegExp conditional="EnableFanArt" output="&lt;url function=&quot;GetTMDBFanartByIMDBId&quot;&gt;http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=tt$$6&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="5">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="EnableIMPAwards" output="&lt;url function=&quot;GetIMPALink&quot;cache=&quot;$$2.html&quot;&gt;http://www.imdb.com/title/tt$$6/posters&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="movieposterdb" output="&lt;url function=&quot;GetMoviePosterDBLink&quot;&gt;http://www.movieposterdb.com/browse/search?type=movies&amp;amp;query=$$6&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="EnableIMDBPosters" output="&lt;url function=&quot;GetIMDBPoster&quot;cache=&quot;$$2.html&quot;&gt;http://www.imdb.com/title/tt$$6/posters&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GoogleToIMDB>
+
+ <GetFilmAffinityPosters dest="5">
+ <RegExp input="$$10" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb&gt;http://pics.filmaffinity.com/\4&lt;/thumb&gt;" dest="10">
+ <expression repeat="yes" noclean="1">, imgs_([0-9]*):([^']*)'([^']*)', url_l: 'http://pics.filmaffinity.com/([^']*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetFilmAffinityPosters>
+</scraper>
diff --git a/system/scrapers/video/filmdelta.png b/system/scrapers/video/filmdelta.png
new file mode 100644
index 0000000000..2b5864f351
--- /dev/null
+++ b/system/scrapers/video/filmdelta.png
Binary files differ
diff --git a/system/scrapers/video/filmdelta.xml b/system/scrapers/video/filmdelta.xml
new file mode 100644
index 0000000000..fdbcf31ff6
--- /dev/null
+++ b/system/scrapers/video/filmdelta.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<scraper framework="1.1" date="2009-08-11" content="movies" name="Filmdelta.se" thumb="filmdelta.png" language="sv">
+ <include>common/tmdb.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Fanart&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetSettings>
+
+ <CreateSearchUrl clearbuffers="no" dest="3">
+ <RegExp input="$$1" output="http://www.filmdelta.se/search.php?string=\1&amp;type=movie&amp;more=1" dest="3">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>%28(.*?)%29</expression>
+ </RegExp>
+ <expression trim="1"/>
+ </RegExp>
+ </CreateSearchUrl>
+
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;year&gt;\3&lt;/year&gt;&lt;url&gt;http://www.filmdelta.se/filmer/\1&lt;/url&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes" noclean="1">&lt;a href="/filmer/([^"]*)"&gt;([^&lt;]*)&lt;/a&gt; \(([0-9]*)\)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;year&gt;$$9&lt;/year&gt;&lt;url&gt;http://www.filmdelta.se/filmer/\1&lt;/url&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes" noclean="1">&lt;a href="/filmer/([^"]*)"&gt;([^&lt;]*)&lt;/a&gt; \($$9\)</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetSearchResults>
+
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression noclean="1">&lt;title&gt; (.*?) - Filmdelta -</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;&lt;runtime&gt;\2&lt;/runtime&gt;" dest="5+">
+ <expression noclean="1">([0-9]*)&lt;/a&gt;, ([0-9]*) min</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;&lt;outline&gt;\1&lt;/outline&gt;" dest="5+">
+ <expression trim="1">&lt;div class="text"&gt;[^&lt;]*&lt;p&gt;(.*?)&lt;/p&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\2&lt;/role&gt;&lt;/actor&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">&lt;div class="info" id="actors"&gt;(.*?)&lt;/div&gt;</expression>
+ </RegExp>
+ <expression repeat="yes" trim="1,2">/'&gt;([^&lt;]*)&lt;/a&gt; - ([^&lt;]*)&lt;/h5&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">&lt;h4&gt;Regiss&amp;ouml;r&lt;/h4&gt;(.*?)&lt;/div&gt;</expression>
+ </RegExp>
+ <expression repeat="yes" trim="1">/'&gt;([^&lt;]*)&lt;/a&gt;&lt;/h5&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="6+">
+ <expression noclean="1">&lt;h4&gt;Manus&lt;/h4&gt;(.*?)&lt;/div&gt;</expression>
+ </RegExp>
+ <expression repeat="yes" trim="1">/'&gt;([^&lt;]*)&lt;/a&gt;&lt;/h5&gt;</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression noclean="1">&lt;h4&gt;Kategori&lt;/h4&gt;(.*?)&lt;/div&gt;</expression>
+ </RegExp>
+ <expression repeat="yes" trim="1">type=category'&gt;([^&lt;]*)&lt;/a&gt;&lt;/h5&gt;</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;url cache=&quot;filmdelta-trans.xml&quot; function=&quot;GetTMDBThumbsByIMDBId&quot;&gt;http://www.google.com/search?q=site:imdb.com\1&lt;/url&gt;" dest="5+">
+ <RegExp input="$$1" output="&quot;\1&quot;+\2" dest="4+">
+ <expression>&lt;h4&gt;Originaltitel&lt;/h4&gt;[^&lt;]*&lt;h5&gt;([^&lt;]*)&lt;/h5&gt;.*?/filmarkiv/([0-9]*)/</expression>
+ </RegExp>
+ <RegExp input="$$4" output="+\1" dest="9+">
+ <expression repeat="yes">([^ ,]+)</expression>
+ </RegExp>
+ <expression/>
+ </RegExp>
+ <RegExp conditional="fanart" input="$$9" output="&lt;url cache=&quot;filmdelta-trans.xml&quot; function=&quot;GetTMDBFanartByIMDBId&quot;&gt;http://www.google.com/search?q=site:imdb.com\1&lt;/url&gt;" dest="5+">
+ <RegExp input="$$1" output="&quot;\1&quot;+\2" dest="4+">
+ <expression>&lt;h4&gt;Originaltitel&lt;/h4&gt;[^&lt;]*&lt;h5&gt;([^&lt;]*)&lt;/h5&gt;.*?/filmarkiv/([0-9]*)/</expression>
+ </RegExp>
+ <RegExp input="$$4" output="+\1" dest="9+">
+ <expression repeat="yes">([^ ,]+)</expression>
+ </RegExp>
+ <expression/>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetDetails>
+</scraper>
diff --git a/system/scrapers/video/filmstarts.jpg b/system/scrapers/video/filmstarts.jpg
new file mode 100644
index 0000000000..01c5335e58
--- /dev/null
+++ b/system/scrapers/video/filmstarts.jpg
Binary files differ
diff --git a/system/scrapers/video/filmstarts.xml b/system/scrapers/video/filmstarts.xml
new file mode 100644
index 0000000000..676224405c
--- /dev/null
+++ b/system/scrapers/video/filmstarts.xml
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<scraper framework="1.1" date="2009-08-15" name="Filmstarts" content="movies" thumb="filmstarts.jpg" language="de">
+ <include>common/tmdb.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Fanart&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.filmstarts.de/kritiken/\2.html&lt;/url&gt;" dest="3">
+ <expression clear="yes" noclean="1">(filmstarts.de/kritiken/)(.*).html</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetByIMDBId&quot;&gt;http://www.imdb.com/title/tt\2/externalreviews&lt;/url&gt;" dest="3+">
+ <expression>(imdb.com/)Title\?([0-9]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetByIMDBId&quot;&gt;http://www.imdb.com/title/tt\2/externalreviews&lt;/url&gt;" dest="3+">
+ <expression>(imdb.com/title/tt)([0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+
+ <GetByIMDBId dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.filmstarts.de/kritiken/\1&lt;/url&gt;" dest="3+">
+ <expression noclean="1">&lt;a href=&quot;http://www.filmstarts.de/kritiken/([^&quot;]*)&quot;</expression>
+ </RegExp>
+ </GetByIMDBId>
+
+ <CreateSearchUrl dest="3" SearchStringEncoding="iso-8859-1">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.filmstarts.de/finde.html?t=film&amp;amp;anfrage=\1&amp;amp;x=0&amp;amp;y=0&amp;&lt;/url&gt;" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+
+ <GetSearchResults dest="3">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url&gt;http://www.filmstarts.de/kritiken/\1&lt;/url&gt;;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes">&lt;li&gt;&lt;a href=&quot;/kritiken/([^&quot;]*)&quot;&gt;.*?&lt;span class=&quot;t&quot;&gt;([^&lt;]*)&lt;/span&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;\1&lt;/details&gt;" dest="3">
+
+ <!--Title -->
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5+">
+ <expression trim="1" noclean="1">&lt;title&gt;([^&lt;|^(]*)</expression>
+ </RegExp>
+
+ <!--Original Title-->
+ <RegExp input="$$1" output="&lt;originaltitle&gt;\1&lt;/originaltitle&gt;" dest="5+">
+ <expression>Originaltitel:(.*?)&lt;/div</expression>
+ </RegExp>
+
+ <!--Year Film-->
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression trim="1" noclean="1">genre&quot;.*weak&quot;.*[A-Z]([0-9 ]*) &lt;/div</expression>
+ </RegExp>
+
+ <!--MPAA Film-->
+ <RegExp input="$$1" output="&lt;mpaa&gt;ab \1&lt;/mpaa&gt;" dest="5+">
+ <expression>FSK:.*?Ab ([0-9]*)&lt;</expression>
+ </RegExp>
+
+ <!--Director Film-->
+ <RegExp input="$$1" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <expression trim="1" noclean="1">Regie&lt;/span&gt;.*?class=&quot;name&quot;&gt;(.*?)&lt;/span</expression>
+ </RegExp>
+
+ <!--Studio Film-->
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="5+">
+ <expression trim="1" noclean="1">Verleih:.*?&quot;&gt;(.*?)&lt;/td</expression>
+ </RegExp>
+
+ <!--Runtime Film-->
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression trim="1" noclean="1">Laufzeit:&lt;/span&gt;.*?&quot;&gt;([A-Za-z0-9 ]*)&lt;/td</expression>
+ </RegExp>
+
+ <!--User rating-->
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;&lt;votes&gt;\2&lt;/votes&gt;" dest="5+">
+ <expression trim="1" noclean="1">&quot;Wertung: ([0-9]*) / ([0-9]*)&quot;</expression>
+ </RegExp>
+
+ <!--Genre Film-->
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression trim="1" noclean="1">&lt;div class=&quot;genre&quot;&gt;&lt;a.*?&quot;&gt;(.*?)&lt;/a</expression>
+ </RegExp>
+
+ <!--Writer-->
+ <RegExp input="$$1" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="5+">
+ <expression trim="1" noclean="1">Drehbuch&lt;/span&gt;.*?class=&quot;name&quot;&gt;([A-Za-z ]*)&lt;/span</expression>
+ </RegExp>
+
+ <!--Plot-->
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression trim="1">&quot;text critic topBorder&quot;&gt;([^&lt;]*)&lt;/div</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression trim="1">&quot;text critic topBorder&quot;&gt;.*?&lt;br /&gt;&lt;br /&gt;(.*?)&lt;/div&gt;</expression>
+ </RegExp>
+
+ <!--Actors -->
+ <RegExp input="$$1" output="&lt;url function=&quot;GetActors&quot;&gt;http://www.filmstarts.de/kritiken/\1/castcrew.html&lt;/url&gt;" dest="5+">
+ <expression noclean="1">/kritiken/([-.%a-z0-9A-Z]+)/bilder.html</expression>
+ </RegExp>
+
+ <!--Posters -->
+ <RegExp input="$$1" output="&lt;url function=&quot;GetPosters&quot;&gt;http://www.filmstarts.de/kritiken/\1/bilder.html&lt;/url&gt;" dest="5+">
+ <expression noclean="1">/kritiken/([-.%a-z0-9A-Z]+)/bilder.html</expression>
+ </RegExp>
+
+ <!--URL to Google and Fanart-->
+ <RegExp conditional="fanart" input="$$8" output="&lt;url function=&quot;GetTMDBFanartByIMDBId&quot;&gt;http://www.google.com/search?q=site:imdb.com\1&lt;/url&gt;" dest="5+">
+ <RegExp input="$$1" output="&quot;\1&quot;+\3+||+&quot;\2&quot;" dest="7">
+ <expression>&lt;title&gt;([^&lt;|^(]*).*Originaltitel:(.*?)&lt;/div&gt;.*weak&quot;.*[A-Z]([0-9 ]*) &lt;/div</expression>
+ </RegExp>
+ <RegExp input="$$7" output="+\1" dest="8+">
+ <expression repeat="yes">([^ ,]+)</expression>
+ </RegExp>
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+
+ <!--Poster-->
+ <GetPosters dest="5">
+ <RegExp input="$$2" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;&gt;&lt;details&gt;\1&lt;/details&gt;" dest="5+">
+ <RegExp input="$$1" output="&lt;thumb preview=&quot;http://thumbs.filmstarts.de/image/\1&quot;&gt;http://thumbs.filmstarts.de/wallpaper/\1&lt;/thumb&gt;" dest="2">
+ <expression repeat="yes">src=&quot;http://thumbs.filmstarts.de/mini/([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetPosters>
+
+ <!--Actors-->
+ <GetActors dest="5">
+ <RegExp input="$$2" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;&gt;&lt;details&gt;\1&lt;/details&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="7+">
+ <expression noclean="1">Schauspieler&lt;/li&gt;(.*)</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;thumb&gt;http://thumbs.filmstarts.de/wallpaper/\2&lt;/thumb&gt;&lt;role&gt;\3&lt;/role&gt;&lt;/actor&gt;" dest="2+">
+ <expression repeat="yes" >img alt=&quot;([^&quot;]*)&quot;.*?src=&quot;http://thumbs.filmstarts.de/nano/([^&quot;]*)&quot;.*?role weak.*?&quot;&gt;als ([A-Za-z ]*)&lt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\2&lt;/role&gt;&lt;/actor&gt;" dest="2+">
+ <expression repeat="yes" >img alt=&quot;([^&quot;]*)&quot;.*?src=&quot;/designs/default/images/no_avatar_small.gif&quot;.*?role weak.*?&quot;&gt;als ([A-Za-z ]*)&lt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;" dest="2+">
+ <expression repeat="yes" >class=&quot;name&quot;&gt;([A-Za-z ]*)&lt;/span</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetActors>
+</scraper>
diff --git a/system/scrapers/video/filmup.gif b/system/scrapers/video/filmup.gif
new file mode 100644
index 0000000000..c67b7750fe
--- /dev/null
+++ b/system/scrapers/video/filmup.gif
Binary files differ
diff --git a/system/scrapers/video/filmup.xml b/system/scrapers/video/filmup.xml
new file mode 100644
index 0000000000..3bb5fc9725
--- /dev/null
+++ b/system/scrapers/video/filmup.xml
@@ -0,0 +1,85 @@
+<scraper framework="1.0" date="2009-05-22" name="FilmUP.it" content="movies" thumb="filmup.gif" language="it">
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://filmup.leonardo.it/sc_\1.htm&lt;/url&gt;" dest="3">
+ <expression noclean="1">sc_([a-z0-9__]*)\.htm</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="http://filmup.leonardo.it/cgi-bin/search.cgi?ps=10&amp;fmt=long&amp;q=\1&amp;ul=%25%2Fsc_%25&amp;m=all&amp;wf=222210&amp;o=0&amp;ps=50" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url&gt;http://filmup.leonardo.it/sc_\1.htm&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes">&lt;a class=&quot;filmup&quot; href=&quot;http.[^sc_]*sc_([0-9a-z_]*)\.htm&quot;[^&gt;]*&gt;[^:]*: (.[^\n]*[^&gt;]*)&gt;</expression>
+
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+
+
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+
+ <!--Title -->
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression trim="1" noclean="1">&lt;title&gt;FilmUP - Scheda: ([^&lt;]*)&lt;</expression>
+ </RegExp>
+
+ <!--Original Title
+ <RegExp input="$$1" output="&lt;originaltitle&gt;\1&lt;/originaltitle&gt;" dest="5">
+ <expression>Titolo originale.[^z]*ze=&quot;2&quot;&gt;([^)&lt;]*)</expression>
+ </RegExp> -->
+
+ <!--Year Film-->
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>Anno.[^z]*ze=&quot;2&quot;&gt;([0-9]*)&lt;</expression>
+ </RegExp>
+
+ <!--Director-->
+ <RegExp input="$$1" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <expression>Regia.[^z]*ze=&quot;2&quot;&gt;([^\n]*)&lt;/font&gt;</expression>
+ </RegExp>
+
+
+
+ <!--Runtime Film-->
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression>Durata.[^z]*ze=&quot;2&quot;&gt;([^)&lt;]*)</expression>
+ </RegExp>
+
+ <!--Genre Film-->
+ <RegExp input="$$6" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression>Genere.[^z]*ze=&quot;2&quot;&gt;([^)&lt;]*)</expression>
+ </RegExp>
+ <expression repeat="yes">([a-zA-Z][^,]*)</expression>
+ </RegExp>
+
+ <!--Plot outline -->
+ <RegExp input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>Trama:&lt;br&gt;([^&lt;]*)</expression>
+ </RegExp>
+
+ <!--Thumbnail -->
+ <RegExp input="$$1" output="&lt;thumb&gt;http://filmup.leonardo.it/locand/\1&lt;/thumb&gt;" dest="5+">
+ <expression noclean="1">src=&quot;locan[^/]*/(.[^&quot;]*)</expression>
+ </RegExp>
+
+ <!--Actors -->
+ <RegExp input="$$7" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression trim="1">Cast.[^z]*ze=&quot;2&quot;&gt;([^\n]*)&lt;/td&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">([a-zA-Z][^,]*)</expression>
+ </RegExp>
+
+
+
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+</scraper>
+
diff --git a/system/scrapers/video/filmweb.jpg b/system/scrapers/video/filmweb.jpg
new file mode 100644
index 0000000000..3618334e08
--- /dev/null
+++ b/system/scrapers/video/filmweb.jpg
Binary files differ
diff --git a/system/scrapers/video/filmweb.xml b/system/scrapers/video/filmweb.xml
new file mode 100644
index 0000000000..0e02bbbb17
--- /dev/null
+++ b/system/scrapers/video/filmweb.xml
@@ -0,0 +1,194 @@
+п»ї<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<scraper framework="1.0" date="2009-08-08" name="filmweb.pl" content="movies" thumb="filmweb.jpg" language="pl">
+ <include>common/tmdb.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Wysoka jakosc okladki&quot; type=&quot;bool&quot; id=&quot;poster&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Pelna obsada&quot; type=&quot;bool&quot; id=&quot;fullcredits&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.filmweb.pl/f\1/xbmc,2008&lt;/url&gt;" dest="3">
+ <expression noclean="1">filmweb.pl/f([0-9]*)/</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url&gt;http://www.filmweb.pl/f\1/xbmc,2008&lt;/url&gt;" dest="3+">
+ <expression noclean="1">Film.id=([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url&gt;http://\1.filmweb.pl&lt;/url&gt;" dest="3+">
+ <expression noclean="1">http://([^\/]+).filmweb.pl</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="http://www.filmweb.pl/szukaj/film?sort=COUNT&amp;q=\1" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="\3\6#\2\5#\1\4#" dest="4">
+ <expression repeat="yes">src=&quot;http://gfx.filmweb.pl/po/[^/]*/[^/]*/([0-9]*)/.[^#]*&quot;&gt;(.[^(]+)\(([0-9]+)|searchResultTitle&quot; href=[^=]*=([0-9]*)&quot;&gt;(.[^(]*)\(([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$4" output="\1" dest="7">
+ <expression>([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$4" output="\1" dest="7+">
+ <expression repeat="yes">[^&gt;]&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;entity&gt;&lt;title&gt;(\1) \2&lt;/title&gt;&lt;url&gt;http://www.filmweb.pl/Film?id=\3&lt;/url&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes">([0-9]+)#([^#]+)#([0-9]+)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails clearbuffers="no" dest="3">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression trim="1">film-title[^=]+[^&gt;]+[^[0-9A-ZЕ»Е№Д†ЕѓД„ЕљЕЃД]+([^&lt;]+[0-9a-zД…Д™ЕјЕєД‡Е›Е„Е‚])</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression>Filmweb.globals.filmId = ([0-9]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>title&gt;.[^&lt;]*\(([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;votes&gt;\1&lt;/votes&gt;" dest="5+">
+ <expression>gЕ‚osГіw:[^&gt;]+&gt;([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1.\2&lt;/rating&gt;" dest="5+">
+ <expression>Ељrednia ocena:[^,]+&gt;([0-9]*),([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;top250&gt;\1&lt;/top250&gt;" dest="5+">
+ <expression>wiat: ([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;studio&gt;\1\2&lt;/studio&gt;" dest="5+">
+ <expression noclean="1">dyst.:[^=]+[^&gt;]+&gt;([^&lt;]+)&lt;/a&gt;|dyst.:[^[A-Z]+([^&lt;]+[a-z])</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;tagline&gt;\1&lt;/tagline&gt;" dest="5+">
+ <expression>recezje-header&quot;[^&lt;]+[^&quot;]+&gt;([^&lt;]+)&lt;/</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;runtime&gt;\1 min&lt;/runtime&gt;" dest="5+">
+ <expression>czas trwania: ([0-9]*)</expression>
+ </RegExp>
+ <RegExp conditional="!poster" input="$$1" output="&lt;thumb&gt;http://gfx.filmweb.pl/po\1&lt;/thumb&gt;" dest="5+">
+ <expression noclean="1">src=&quot;http://gfx.filmweb.pl/po(.[^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;outline&gt;\2...&lt;/outline&gt;" dest="5+">
+ <expression>o-filmie-header&quot;[^&lt;]+[^ ]+(&gt;[^[0-9A-Z]+)([^&lt;]+[a-z])</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">gatunek[^=]*[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <RegExp input="$$6" output=" / \1" dest="7">
+ <expression repeat="yes">([^,]+)</expression>
+ </RegExp>
+ <expression> / (.*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">yseria[^-]+([^~]*)o-filmie-header</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="5+">
+ <RegExp input="$$6" output=" / \1" dest="7">
+ <expression repeat="yes">title=&quot;[^&gt;]+&gt;([^&lt;]+)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression> / (.*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <expression noclean="1">yseria[^&gt;]+&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp conditional="!fullcredits" input="$$1" output="\1" dest="6">
+ <expression noclean="1">obsada-header([^~]*)zobacz wiД™cej</expression>
+ </RegExp>
+ <RegExp conditional="!fullcredits" input="$$6" output="&lt;actor&gt;&lt;name&gt;\1\3&lt;/name&gt;&lt;role&gt;\2\4&lt;/role&gt;&lt;/actor&gt;" dest="5+">
+ <expression repeat="yes" trim="1,3,4">src=&quot;[^&gt;]+[^[a-zA-Z]+([^\n]+)[^h]+href=[^&gt;]+&gt;([^&lt;]+)&lt;/a&gt;|src=&quot;[^&gt;]+[^[a-zA-Z]+([^\n]+)[^=]*[^&gt;]+[^[a-zA-Z]+([^\n]+)</expression>
+ </RegExp>
+ <RegExp conditional="!fullcredits" input="$$6" output="&lt;actor&gt;&lt;thumb&gt;http://gfx.filmweb.pl/p/\1.1.jpg&lt;/thumb&gt;&lt;name&gt;\2&lt;/name&gt;&lt;/actor&gt;" dest="5+">
+ <expression repeat="yes" trim="1,2">src=&quot;http://gfx.filmweb.pl/p/([^\.]+)[^&gt;]+[^[a-zA-Z]+([^\n]+)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;url function=&quot;FilmwebToWikipedia&quot;&gt;http://pl.wikipedia.org/w/index.php?title=Specjalna%3ALinksearch&amp;amp;target=http://www.filmweb.pl/Film?id=$$9&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="fullcredits" input="$$1" output="&lt;url function=&quot;Obsada&quot; &gt;http://\1.filmweb.pl/f\2/xbmc,2008/obsada&lt;/url&gt;" dest="5+">
+ <expression>http://([^\/]+).filmweb.pl/f([0-9]*)/[^&gt;]+&quot;&gt;peЕ‚na obsada&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;url function=&quot;Zwiastuny&quot; &gt;http://www.filmweb.pl/f$$9/xbmc,2008/zwiastuny&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;url function=&quot;Opisy&quot;&gt;http://www.filmweb.pl/f$$9/xbmc,2008/opisy&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="poster" input="$$9" output="&lt;url function=&quot;Plakaty&quot;&gt;http://www.filmweb.pl/f$$9/xbmc,2008/plakaty&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+ <FilmwebToWikipedia clearbuffers="no" dest="5">
+ <RegExp input="$$2" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="10">
+ <expression>id=$$9&lt;/a&gt; linkuje z [^&gt;]+&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$11" output="&lt;url function=&quot;GetTMDBFanartByIMDBId&quot;&gt;http://pl.wikipedia.org/wiki/\1&lt;/url&gt;" dest="2+">
+ <RegExp input="$$10" output="_\1" dest="11">
+ <expression repeat="yes">([^ ]+)</expression>
+ </RegExp>
+ <expression>_(.*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </FilmwebToWikipedia>
+ <Opisy dest="5">
+ <RegExp input="$$8" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;&lt;plot&gt;\1&lt;/plot&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1\n" dest="9">
+ <expression>distributors.description.0\][^\[]*justify&quot;&gt;(.[^=]*)&lt;/p&gt;&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="9+">
+ <expression>opisy-header[^\[]*justify&quot;&gt;([^&quot;]*)&lt;/p&gt;&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$9" output="\1" dest="8">
+ <expression>([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$9" output=" \1" dest="8+">
+ <expression repeat="yes">&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <expression trim="1">[^[0-9A-ZЕ»Е№Д†ЕѓД„ЕљЕЃД]+([^~]+[0-9a-zД…Д™ЕјЕєД‡Е›Е„Е‚\]\.])</expression>
+ </RegExp>
+ </Opisy>
+ <Plakaty dest="5">
+ <RegExp input="$$8" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb&gt;http://gfx.filmweb.pl/po\1&lt;/thumb&gt;" dest="8+">
+ <expression noclean="1" repeat="yes">href=&quot;http://gfx.filmweb.pl/po(.[^&quot;]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </Plakaty>
+ <Obsada dest="5">
+ <RegExp input="$$8" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">col&quot;&gt;aktorzy&lt;/th([^~]*)class=&quot;film-poster&quot;</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;actor&gt;&lt;name&gt;\1\3&lt;/name&gt;&lt;role&gt;\2\4&lt;/role&gt;&lt;/actor&gt;" dest="8+">
+ <expression repeat="yes" trim="1,3,4">src=&quot;[^&gt;]+[^[a-zA-Z]+([^\n]+)[^h]+href=[^&gt;]+&gt;([^&lt;]+)&lt;/a&gt;|src=&quot;[^&gt;]+[^[a-zA-Z]+([^\n]+)[^=]*=&quot;film-protagonist[^&gt;]+[^[a-zA-Z]+([^\n]+)&amp;nbsp;</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;actor&gt;&lt;thumb&gt;http://gfx.filmweb.pl/p/\1.1.jpg&lt;/thumb&gt;&lt;name&gt;\2&lt;/name&gt;&lt;/actor&gt;" dest="8+">
+ <expression repeat="yes" trim="1,2">src=&quot;http://gfx.filmweb.pl/p/([^\.]+)[^&gt;]+[^[a-zA-Z]+([^\n]+)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </Obsada>
+ <Zwiastuny dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;url function=&quot;GetTrailerLink&quot;&gt;http://www.filmweb.pl/Trailer\1&lt;/url&gt;&lt;/details&gt;" dest="5">
+ <expression clear="yes" noclean="1">href=&quot;/Trailer([^&quot;]+)&quot;>[^\n]*[^[0-9]+4</expression>
+ </RegExp>
+ </Zwiastuny>
+ <GetTrailerLink dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;trailer&gt;\1&lt;/trailer&gt;&lt;/details&gt;" dest="5">
+ <expression clear="yes" noclean="1">param name=&quot;src&quot; value=&quot;([^&quot;]+)</expression>
+ </RegExp>
+ </GetTrailerLink>
+</scraper>
diff --git a/system/scrapers/video/imdb tv.xml b/system/scrapers/video/imdb tv.xml
new file mode 100644
index 0000000000..78f6276cd2
--- /dev/null
+++ b/system/scrapers/video/imdb tv.xml
@@ -0,0 +1,218 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.0" date="2009-08-10" name="IMDb TV" content="tvshows" thumb="imdb.png" language="en">
+ <include>common/movieposterdb.xml</include>
+ <include>common/impa.xml</include>
+ <include>common/imdb.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Full Cast Credits&quot; type=&quot;bool&quot; id=&quot;fullcredits&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable IMPAwards&quot; type=&quot;bool&quot; id=&quot;impawards&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable MoviePosterDB&quot; type=&quot;bool&quot; id=&quot;movieposterdb&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;IMDB Poster &amp;amp; Actor Thumb(s) Size&quot; type=&quot;labelenum&quot; values=&quot;192|256|384|512|1024&quot; id=&quot;imdbscale&quot; default=&quot;192&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting type=&quot;sep&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Input Alternative IMDb Source&quot; type=&quot;text&quot; id=&quot;url&quot; default=&quot;akas.imdb.com&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://akas.imdb.com/title/tt\1/&lt;/url&gt;&lt;id&gt;tt\1&lt;/id&gt;" dest="3">
+ <expression clear="yes" noclean="1">imdb.com/Title\?([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url&gt;http://akas.imdb.com/title/tt\1/&lt;/url&gt;&lt;id&gt;tt\1&lt;/id&gt;" dest="3+">
+ <expression clear="yes" noclean="1">imdb.com/title/tt([0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://$INFO[url]/find?s=tt;q=\1&lt;/url&gt;" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression clear="yes">/title/([t0-9]*)/faq</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\1 (\2)&lt;/title&gt;&lt;url&gt;http://$INFO[url]/title/$$7/&lt;/url&gt;&lt;id&gt;$$7&lt;/id&gt;&lt;/entity&gt;" dest="5">
+ <expression clear="yes" noclean="1">&lt;meta name=&quot;title&quot; content=&quot;([^&quot;]*) \(([0-9]*)\)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="4">
+ <expression noclean="1">(&gt;&lt;a href=&quot;/title.*)</expression>
+ </RegExp>
+ <RegExp input="$$4" output="&lt;entity&gt;&lt;title&gt;\2 (\3)&lt;/title&gt;&lt;url&gt;http://$INFO[url]/title/\1/&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes" noclean="1,2">&gt;&lt;a href=&quot;/title/([t0-9]*)/[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt; *\(([0-9]*)</expression>
+ </RegExp>
+ <expression clear="yes" noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails clearbuffers="no" dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression trim="1" noclean="1">&lt;title&gt;[^;]*;([^&amp;]*)[^;]*;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>a href=&quot;/Sections/Years/([0-9]*)&quot;&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;&lt;votes&gt;\2&lt;/votes&gt;" dest="5+">
+ <expression>&lt;b&gt;User Rating:&lt;/b&gt;[^&lt;]*&lt;b&gt;([0-9.]+)/10&lt;/b&gt;[^&lt;]*&lt;small&gt;\(&lt;a href=&quot;ratings&quot;&gt;([0-9,]+) votes&lt;/a&gt;\)&lt;/small&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes">&quot;/Sections/Genres/[^/]*/&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;url function=&quot;GetSeriesPremiered&quot;&gt;http://$INFO[url]/title/\1/episodes&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;url function=&quot;GetSeriesPlot&quot;&gt;http://$INFO[url]/title/\1/plotsummary&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="!fullcredits" input="$$2" output="&lt;url cache=&quot;$$2-credits.html&quot; function=&quot;GetSeriesCast&quot;&gt;http://$INFO[url]/title/\1/&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="fullcredits" input="$$2" output="&lt;url cache=&quot;$$2-credits.html&quot; function=&quot;GetSeriesCast&quot;&gt;http://$INFO[url]/title/\1/fullcredits#cast&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="impawards" input="$$2" output="&lt;url cache=&quot;$$2-posters.html&quot; function=&quot;GetIMPALink&quot;&gt;http://$INFO[url]/title/\1/posters&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="movieposterdb" input="$$1" output="&lt;url function=&quot;GetMoviePosterDBLink&quot;&gt;http://www.movieposterdb.com/browse/search?type=movies&amp;amp;query=\1&lt;/url&gt;" dest="5+">
+ <expression>/title/tt([t0-9]*)/faq</expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;url cache=&quot;$$2-posters.html&quot; function=&quot;GetIMDBThumbs&quot;&gt;http://$INFO[url]/title/\1/posters&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;episodeguide&gt;&lt;url&gt;http://www.imdb.com/title/\1/episodes&lt;/url&gt;&lt;/episodeguide&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+ <GetSeriesPremiered clearbuffers="no" dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;premiered&gt;\1&lt;/premiered&gt;&lt;/details&gt;" dest="5">
+ <expression>Original Air Date: ([^&lt;]*)&lt;</expression>
+ </RegExp>
+ </GetSeriesPremiered>
+ <GetSeriesPlot clearbuffers="no" dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;&lt;plot&gt;\1&lt;/plot&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="2">
+ <expression>&lt;p class="plotpar"&gt;\n([^\n]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSeriesPlot>
+ <GetSeriesCast clearbuffers="no" dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">&lt;table class=&quot;cast&quot;&gt;(.*?)&lt;/table&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;thumb&gt;\1_SY$INFO[imdbscale]_\2&lt;/thumb&gt;&lt;name&gt;\3&lt;/name&gt;&lt;role&gt;\4&lt;/role&gt;&lt;/actor&gt;" dest="7">
+ <expression repeat="yes" noclean="1,2" trim="3,4">&lt;img src=&quot;(?:([^&quot;]*VM\.)[^&quot;]*(\.jpg))?[^&gt;]*[^&quot;]*&quot;nm&quot;&gt;&lt;a href=&quot;[^&quot;]*&quot;&gt;([^&lt;]*)&lt;[^&quot;]*&quot;ddd&quot;&gt; ... [^&quot;]*&quot;char&quot;&gt;(.*?)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;actor&gt;&lt;thumb&gt;\1&lt;/thumb&gt;\2&lt;/actor&gt;" dest="2+">
+ <expression repeat="yes" noclean="1,2,3">&lt;actor&gt;&lt;thumb&gt;(?:(http.*?)|_SY[0-9]+_)&lt;/thumb&gt;(.*?)&lt;/actor&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSeriesCast>
+ <GetEpisodeList dest="9">
+ <RegExp input="$$4" output="&lt;episodeguide&gt;\1&lt;/episodeguide&gt;" dest="9">
+ <RegExp input="$$1" output="&lt;episode&gt;&lt;title&gt;\4&lt;/title&gt;&lt;url&gt;http://$INFO[url]/title/\3/&lt;/url&gt;&lt;epnum&gt;\2&lt;/epnum&gt;&lt;season&gt;\1&lt;/season&gt;&lt;id&gt;\3&lt;/id&gt;&lt;/episode&gt;" dest="4">
+ <expression repeat="yes">&lt;a name=&quot;year-[0-9]+&quot;&gt; &lt;/a&gt;&lt;h4&gt;Season ([0-9]*), Episode ([0-9]*): &lt;a href=&quot;/title/([^&quot;]*)/&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetEpisodeList>
+ <GetEpisodeDetails dest="9">
+ <RegExp input="$$4" output="&lt;details&gt;\1&lt;/details&gt;" dest="9">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="4">
+ <expression trim="1" noclean="1">&lt;title&gt;[^;]*;[^;]*; ([^&lt;|^(]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;season&gt;\1&lt;/season&gt;" dest="4+">
+ <expression>(Season ([0-9]*), Episode [0-9]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;episode&gt;\1&lt;/episode&gt;" dest="4+">
+ <expression>(Season [0-9]+, Episode ([0-9]*))</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">&lt;h5&gt;Director(.*)&lt;h5&gt;Writer</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;director&gt;\1&lt;/director&gt;" dest="4+">
+ <expression repeat="yes">&lt;a href=&quot;/name/[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="4+">
+ <expression repeat="yes">&quot;/Sections/Genres/[^/]*/&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;aired&gt;\1&lt;/aired&gt;" dest="4+">
+ <expression trim="1">&lt;div class=&quot;info&quot;&gt;[^&lt;]*&lt;h5&gt;Original Air Date:&lt;/h5&gt;([^\(]*)\(</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">&lt;h5&gt;Writer[^&gt;]*([^;]*)</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="4+">
+ <RegExp input="$$6" output=" / \1" dest="7">
+ <expression repeat="yes">&lt;a href=&quot;/name/[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <expression> / (.*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;&lt;votes&gt;\2&lt;/votes&gt;" dest="4+">
+ <expression>&lt;b&gt;User Rating:&lt;/b&gt;[^&lt;]*&lt;b&gt;([0-9.]+)/10&lt;/b&gt;[^&lt;]*&lt;small&gt;\(&lt;a href=&quot;ratings&quot;&gt;([0-9,]+) votes&lt;/a&gt;\)&lt;/small&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">first billed only: &lt;/b&gt;&lt;/td&gt;&lt;/tr&gt;(.*)</expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;url function=&quot;GetEpisodePlot&quot;&gt;http://$INFO[url]/title/\1/plotsummary&lt;/url&gt;" dest="4+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="!fullcredits" input="$$2" output="&lt;url function=&quot;GetEpisodeCast&quot;&gt;http://$INFO[url]/title/\1/&lt;/url&gt;" dest="4+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="fullcredits" input="$$2" output="&lt;url function=&quot;GetEpisodeCast&quot;&gt;http://$INFO[url]/title/\1/fullcredits#cast&lt;/url&gt;" dest="4+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetEpisodeRuntime&quot;&gt;http://$INFO[url]/title/\1&lt;/url&gt;" dest="4+">
+ <expression>&lt;h5&gt;TV Series:&lt;/h5&gt;[^&lt;]*&lt;a href=&quot;/title/([^/]*)/&quot;&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetEpisodeDetails>
+ <GetEpisodePlot dest="4">
+ <RegExp input="$$2" output="&lt;details&gt;&lt;plot&gt;\1&lt;/plot&gt;&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="\1" dest="2">
+ <expression>&lt;p class="plotpar"&gt;\n([^\n]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetEpisodePlot>
+ <GetEpisodeCast dest="4">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">&lt;table class=&quot;cast&quot;&gt;(.*?)&lt;/table&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;thumb&gt;\1_SY$INFO[imdbscale]_\2&lt;/thumb&gt;&lt;name&gt;\3&lt;/name&gt;&lt;role&gt;\4&lt;/role&gt;&lt;/actor&gt;" dest="7">
+ <expression repeat="yes" noclean="1,2" trim="3,4">&lt;img src=&quot;(?:([^&quot;]*VM\.)[^&quot;]*(\.jpg))?[^&gt;]*[^&quot;]*&quot;nm&quot;&gt;&lt;a href=&quot;[^&quot;]*&quot;&gt;([^&lt;]*)&lt;[^&quot;]*&quot;ddd&quot;&gt; ... [^&quot;]*&quot;char&quot;&gt;(.*?)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;actor&gt;&lt;thumb&gt;\1&lt;/thumb&gt;\2&lt;/actor&gt;" dest="2+">
+ <expression repeat="yes" noclean="1,2,3">&lt;actor&gt;&lt;thumb&gt;(?:(http.*?)|_SY[0-9]+_)&lt;/thumb&gt;(.*?)&lt;/actor&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetEpisodeCast>
+ <GetEpisodeRuntime dest="4">
+ <RegExp input="$$2" output="&lt;details&gt;&lt;runtime&gt;\1&lt;/runtime&gt;&lt;/details&gt;" dest="4">
+ <RegExp input="$$1" output="\1" dest="2">
+ <expression trim="1">&lt;h5&gt;Runtime:&lt;/h5&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetEpisodeRuntime>
+</scraper>
diff --git a/system/scrapers/video/imdb-cn.gif b/system/scrapers/video/imdb-cn.gif
new file mode 100644
index 0000000000..7d12a89f2b
--- /dev/null
+++ b/system/scrapers/video/imdb-cn.gif
Binary files differ
diff --git a/system/scrapers/video/imdb-cn.xml b/system/scrapers/video/imdb-cn.xml
new file mode 100644
index 0000000000..694186a300
--- /dev/null
+++ b/system/scrapers/video/imdb-cn.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="gb2312"?>
+<scraper framework="1.1" date="2009-08-10" name="IMDb-CN(Chinese)" content="movies" thumb="imdb-cn.gif" language="zh">
+ <include>common/tmdb.xml</include>
+ <include>common/movieposterdb.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable MoviePosterDB&quot; type=&quot;bool&quot; id=&quot;movieposterdb&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Fanart&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.imdb.cn/title/tt\1&lt;/url&gt;&lt;id&gt;tt\1&lt;/id&gt;" dest="3">
+ <expression clear="yes" noclean="1">imdb.cn/title/tt([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url&gt;http://www.imdb.cn/title/tt\1&lt;/url&gt;&lt;id&gt;tt\1&lt;/id&gt;" dest="3+">
+ <expression clear="yes" noclean="1">imdb.com/Title\?([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url&gt;http://www.imdb.cn/title/tt\1&lt;/url&gt;&lt;id&gt;tt\1&lt;/id&gt;" dest="3+">
+ <expression clear="yes" noclean="1">imdb.com/title/tt([0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateSearchUrl dest="3" SearchStringEncoding="gb2312">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.imdb.cn/searchh.php?keyword=\1&amp;amp;a=search&amp;amp;Type=movie&lt;/url&gt;" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;gb2312&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression clear="yes">/title/([t0-9]*)/ratings</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression clear="yes">&lt;td colspan=2&gt;&lt;span class=mn&gt;([^&lt;]*)&lt;/span&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\1 - $$6 (\2)&lt;/title&gt;&lt;url&gt;http://www.imdb.cn/title/$$7&lt;/url&gt;&lt;id&gt;\$$7&lt;/id&gt;&lt;/entity&gt;" dest="5">
+ <expression clear="yes" noclean="1">&lt;h1&gt;([^&lt;]*)&lt;/h1&gt;[^&quot;]*&quot;http://www.imdb.cn/Sections/Years/([0-9]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2 - \3 (\4)&lt;/title&gt;&lt;url&gt;http://www.imdb.cn/title/\1&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes" noclean="1,3">&lt;a href=&quot;title/([t0-9]*)&quot; target=&quot;_blank&quot;&gt;(.[^-]*)-(.[^&lt;]*)&lt;/a&gt; - \(([0-9]*)\)</expression>
+ </RegExp>
+ <expression clear="yes" noclean="1"/>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$2" output="&lt;id&gt;\1&lt;/id&gt;" dest="5">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5+">
+ <expression trim="1" noclean="1">&lt;title&gt;([^&lt;|^-]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;originaltitle&gt;\1&lt;/originaltitle&gt;" dest="5+">
+ <expression trim="1" noclean="1">Ж¬ ГыЈє&lt;/span&gt;.*?class=mn&gt;(.[^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>&lt;span class=hhh2&gt;\(([0-9]*)\)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;top250&gt;\1&lt;/top250&gt;" dest="5+">
+ <expression>TOP &lt;font color=red&gt;([0-9]*) &lt;/font>&gt;</expression>
+ </RegExp>
+ <RegExp input="$$4" output="\1" dest="5+">
+ <RegExp input="$$1" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;\n" dest="4">
+ <expression>MPAA[^&lt;]*&lt;/span&gt;&lt;br&gt;(.[^&lt;]*)</expression>
+ </RegExp>
+ <expression repeat="yes" noclean="1">(.*?)\n</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;certification&gt;\1&lt;/certification&gt;" dest="5+">
+ <expression repeat="yes">&lt;a href=http://www.imdb.cn/Sections/Certification/[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$4" output="\1" dest="5+">
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;\n" dest="4">
+ <expression trim="1">&lt;td colspan=&quot;2&quot;&gt;&lt;font color=red&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <expression repeat="yes" noclean="1">(.*?)\n</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;&lt;votes&gt;\2&lt;/votes&gt;" dest="5+">
+ <expression>\.gif&quot; &gt;&lt;b&gt;([0-9.]+)/10&lt;/b&gt; \( ([0-9]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes">&lt;a href=http://www.imdb.cn/Sections/Genre/[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>&lt;div id=imdbjqbody&gt;&lt;h2&gt;[^&lt;]*&lt;/h2&gt;&lt;br&gt;(.*?)&lt;/div</expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;url cache=&quot;$$2-fullcredits.html&quot; function=&quot;GetFullcredits&quot;&gt;$$3/fulldredits&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="movieposterdb" input="$$1" output="&lt;url function=&quot;GetMoviePosterDBLink&quot;&gt;http://www.movieposterdb.com/browse/search?type=movies&amp;amp;query=\1&lt;/url&gt;" dest="5+">
+ <expression>/title/tt([0-9]*)/ratings</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetIMDBCNPoster&quot;&gt;\1&lt;/url&gt;" dest="5+">
+ <expression>&lt;a href=(http://posters.imdb.cn/poster/[0-9]*)</expression>
+ </RegExp>
+ <RegExp conditional="fanart" input="$$2" output="&lt;url function=&quot;GetTMDBFanartByIMDBId&quot;&gt;http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=$$2&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+
+ <GetFullcredits clearbuffers="no" dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression clear="yes" noclean="1">СЭФ± &lt;table(.*?)&lt;/table&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\2&lt;/role&gt;&lt;/actor&gt;" dest="2">
+ <expression repeat="yes" trim="1,2">href=&apos;/name/nm[0-9]+&apos;&gt;([^&lt;]*)&lt;/a&gt;[^\.]*\.\.\.\.\.\.([^&lt;]*)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression clear="yes" noclean="1">µјСЭ &lt;table(.*?)&lt;/table&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;director&gt;\1&lt;/director&gt;" dest="2+">
+ <expression repeat="yes">href=&apos;/name/nm[0-9]+&apos;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression clear="yes" noclean="1">±аѕз &lt;table(.*?)&lt;/table&gt;</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="2+">
+ <expression repeat="yes">href=&apos;/name/nm[0-9]+&apos;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetFullcredits>
+ <GetIMDBCNPoster dest="5">
+ <RegExp input="$$6" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="6">
+ <expression clear="yes" noclean="1">&lt;img src=&quot;(.*?/poster-pic/.*?.jpg)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetIMDBCNPoster>
+</scraper>
diff --git a/system/scrapers/video/imdb.png b/system/scrapers/video/imdb.png
new file mode 100644
index 0000000000..b2edac3fe7
--- /dev/null
+++ b/system/scrapers/video/imdb.png
Binary files differ
diff --git a/system/scrapers/video/imdb.xml b/system/scrapers/video/imdb.xml
new file mode 100644
index 0000000000..7cbdb81389
--- /dev/null
+++ b/system/scrapers/video/imdb.xml
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.1" date="2009-08-10" name="IMDb" content="movies" thumb="imdb.png" language="en">
+ <include>common/imdb.xml</include>
+ <include>common/tmdb.xml</include>
+ <include>common/movieposterdb.xml</include>
+ <include>common/impa.xml</include>
+ <include>common/dtrailer.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Full Cast Credits&quot; type=&quot;bool&quot; id=&quot;fullcredits&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable themoviedb.org&quot; type=&quot;bool&quot; id=&quot;tmdbthumbs&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable IMPAwards&quot; type=&quot;bool&quot; id=&quot;impawards&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable MoviePosterDB&quot; type=&quot;bool&quot; id=&quot;movieposterdb&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable IMDB Trailer&quot; type=&quot;bool&quot; id=&quot;trailer&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable DTrailer.com Trailer&quot; type=&quot;bool&quot; id=&quot;dtrailer&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Fanart&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;IMDB Poster &amp;amp; Actor Thumb(s) Size&quot; type=&quot;labelenum&quot; values=&quot;192|256|384|512|1024&quot; id=&quot;imdbscale&quot; default=&quot;512&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting type=&quot;sep&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Input Alternative IMDb Source&quot; type=&quot;text&quot; id=&quot;url&quot; default=&quot;akas.imdb.com&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.\1/title/tt\2/&lt;/url&gt;&lt;id&gt;tt\2&lt;/id&gt;" dest="3">
+ <expression clear="yes" noclean="1">(imdb.com/)Title\?([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url&gt;http://www.\1\2/&lt;/url&gt;&lt;id&gt;tt\2&lt;/id&gt;" dest="3+">
+ <expression clear="yes" noclean="1">(imdb.com/title/tt)([0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://$INFO[url]/find?s=tt;q=\1$$4&lt;/url&gt;" dest="3">
+ <RegExp input="$$2" output="%20(\1)" dest="4">
+ <expression clear="yes">(.+)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression clear="yes">/title/([t0-9]*)/faq</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\1&lt;/title&gt;&lt;year&gt;\2&lt;/year&gt;&lt;url&gt;http://$INFO[url]/title/$$7/&lt;/url&gt;&lt;id&gt;$$7&lt;/id&gt;&lt;/entity&gt;" dest="5">
+ <expression clear="yes" noclean="1">&lt;meta name=&quot;title&quot; content=&quot;([^&quot;]*) \(([0-9]*)\)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="4">
+ <expression noclean="1">(&gt;&lt;a href=&quot;/title.*)</expression>
+ </RegExp>
+ <RegExp input="$$4" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;year&gt;\3&lt;/year&gt;&lt;url&gt;http://$INFO[url]/title/\1/&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes" noclean="1,2">&gt;&lt;a href=&quot;/title/([t0-9]*)/[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt; *\(([0-9]*)</expression>
+ </RegExp>
+ <expression clear="yes" noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$2" output="&lt;id&gt;\1&lt;/id&gt;" dest="5">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5+">
+ <expression trim="1" noclean="1">&lt;title&gt;([^&lt;|^(]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>a href=&quot;/Sections/Years/([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;top250&gt;\1&lt;/top250&gt;" dest="5+">
+ <expression>Top 250: #([0-9]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;" dest="5+">
+ <expression>MPAA&lt;/a&gt;:&lt;/h5&gt;(.[^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;certification&gt;\1 \3&lt;/certification&gt;" dest="5+">
+ <expression repeat="yes">&lt;a href=&quot;/List\?certificates=[^&quot;]*&quot;&gt;([^&lt;]*)&lt;/a&gt;[^&lt;]*(&lt;i&gt;([^&lt;]*)&lt;/i&gt;)?</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;tagline&gt;\1&lt;/tagline&gt;" dest="5+">
+ <expression>&lt;h5&gt;Tagline:&lt;/h5&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression trim="1">&lt;h5&gt;Runtime:&lt;/h5&gt;[^0-9]*([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;&lt;votes&gt;\2&lt;/votes&gt;" dest="5+">
+ <expression>&lt;b&gt;([0-9.]+)/10&lt;/b&gt;[^&lt;]*&lt;a href=&quot;ratings&quot; class=&quot;tn15more&quot;&gt;([0-9,]+) votes&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes">&quot;/Sections/Genres/[^/]*/&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="5+">
+ <expression repeat="yes">&quot;/company/[^/]*/&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>Plot:&lt;/h5&gt;(.*?) \| &lt;a class=&quot;tn15more</expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;url function=&quot;GetIMDBPlot&quot;&gt;$$3plotsummary&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="!fullcredits" input="$$2" output="&lt;url cache=&quot;$$2-credits.html&quot; function=&quot;GetIMDBCast&quot;&gt;$$3&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="!fullcredits" input="$$2" output="&lt;url cache=&quot;$$2-credits.html&quot; function=&quot;GetIMDBDirectors&quot;&gt;$$3&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="!fullcredits" input="$$2" output="&lt;url cache=&quot;$$2-credits.html&quot; function=&quot;GetIMDBWriters&quot;&gt;$$3&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="fullcredits" input="$$2" output="&lt;url cache=&quot;$$2-fullcredits.html&quot; function=&quot;GetIMDBCast&quot;&gt;$$3fullcredits&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="fullcredits" input="$$2" output="&lt;url cache=&quot;$$2-fullcredits.html&quot; function=&quot;GetIMDBDirectors&quot;&gt;$$3fullcredits&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="fullcredits" input="$$2" output="&lt;url cache=&quot;$$2-fullcredits.html&quot; function=&quot;GetIMDBWriters&quot;&gt;$$3fullcredits&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="tmdbthumbs" input="$$2" output="&lt;url function=&quot;GetTMDBThumbsByIMDBId&quot; cache=&quot;tmdb-trans-\1.xml&quot;&gt;http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=\1&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp conditional="impawards" input="$$2" output="&lt;url cache=&quot;$$2-posters.html&quot; function=&quot;GetIMPALink&quot;&gt;$$3posters&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="movieposterdb" input="$$1" output="&lt;url function=&quot;GetMoviePosterDBLink&quot;&gt;http://www.movieposterdb.com/browse/search?type=movies&amp;amp;query=\1&lt;/url&gt;" dest="5+">
+ <expression>/title/tt([t0-9]*)/faq</expression>
+ </RegExp>
+ <RegExp conditional="trailer" input="$$1" output="&lt;url function=&quot;GetIMDBTrailer&quot;&gt;http://$INFO[url]/video/imdb/vi\1/player&lt;/url&gt;" dest="5+">
+ <expression>/vi([0-9]*)/&quot;</expression>
+ </RegExp>
+ <RegExp conditional="dtrailer" input="$$1" output="&lt;url function=&quot;GetDTrailerLink&quot;&gt;http://en.dtrailer.com/movies/search/\1&lt;/url&gt;" dest="5+">
+ <expression trim="1" noclean="1">&lt;title&gt;([^&lt;|^(]*)</expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;url cache=&quot;$$2-posters.html&quot; function=&quot;GetIMDBThumbs&quot;&gt;$$3posters&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="fanart" input="$$2" output="&lt;url function=&quot;GetTMDBFanartByIMDBId&quot;&gt;http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=$$2&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+</scraper>
diff --git a/system/scrapers/video/jaded.jpg b/system/scrapers/video/jaded.jpg
new file mode 100644
index 0000000000..b5c2fcadc1
--- /dev/null
+++ b/system/scrapers/video/jaded.jpg
Binary files differ
diff --git a/system/scrapers/video/jadedVideo.xml b/system/scrapers/video/jadedVideo.xml
new file mode 100644
index 0000000000..e3b6efb7c2
--- /dev/null
+++ b/system/scrapers/video/jadedVideo.xml
@@ -0,0 +1,47 @@
+<scraper framework="1.0" date="2009-05-22" name="Jaded Video" content="movies" thumb="jaded.jpg" language="en">
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="http://jadedvideo.com/\1" dest="3">
+ <expression noclean="1">jadedvideo\.com/(.*)</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://jadedvideo.com/Search?q=\1&lt;/url&gt;" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ </CreateSearchUrl>
+
+ <GetSearchResults dest="6">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="6">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\3&lt;/title&gt;&lt;url&gt;http://jadedvideo.com/\1&lt;/url&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes">&quot;jadedcatprodtitle&quot;&gt;&lt;a href=&quot;http://jadedvideo\.com/([^&quot;]*)&quot;&gt;&lt;em&gt;([^&gt;]*)&lt;/em&gt; ([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ </GetSearchResults>
+
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;thumb&gt;http://jadedvideo.com/images/CoverFront/320x480/\1.jpg&lt;/thumb&gt;" dest="5">
+ <expression>320x480/([0-9]*).jpg&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5+">
+ <expression>jadedprodtitle&quot;&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;" dest="5+">
+ <expression repeat="yes">&lt;a[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;,</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression>Category&lt;/strong&gt;: &lt;a[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>Date&lt;/strong&gt;[^&lt;]* ([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="5+">
+ <expression>Studio&lt;/strong&gt;: &lt;[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+</scraper>
diff --git a/system/scrapers/video/moviemaze.jpg b/system/scrapers/video/moviemaze.jpg
new file mode 100644
index 0000000000..b810048168
--- /dev/null
+++ b/system/scrapers/video/moviemaze.jpg
Binary files differ
diff --git a/system/scrapers/video/moviemaze.xml b/system/scrapers/video/moviemaze.xml
new file mode 100644
index 0000000000..3c786ba1ae
--- /dev/null
+++ b/system/scrapers/video/moviemaze.xml
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<scraper framework="1.1" date="2009-07-28" name="MovieMaze" content="movies" thumb="moviemaze.jpg" language="de">
+ <include>common/tmdb.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Fanart&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Trailer&quot; type=&quot;bool&quot; id=&quot;trailer&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;\1\2/\3.html&lt;/url&gt;" dest="3">
+ <expression clear="yes" noclean="1">(http://www.moviemaze.de/filme/)([0-9]*)/(.*).html</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetByIMDBId&quot;&gt;http://www.imdb.com/title/tt\2/externalreviews&lt;/url&gt;" dest="3+">
+ <expression>(imdb.com/)Title\?([0-9]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetByIMDBId&quot;&gt;http://www.imdb.com/title/tt\2/externalreviews&lt;/url&gt;" dest="3+">
+ <expression>(imdb.com/title/tt)([0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+
+ <GetByIMDBId dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.moviemaze.de/filme/\1/\2&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;" dest="3+">
+ <expression noclean="1">&lt;a href=&quot;http://www.moviemaze.de/filme/([0-9]*)/([^&quot;]*)</expression>
+ </RegExp>
+ </GetByIMDBId>
+
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="http://www.moviemaze.de/suche/result.phtml?searchword=\1" dest="3">
+ <expression noclean="1"/>
+ </RegExp>
+ </CreateSearchUrl>
+
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\3&lt;/title&gt;&lt;url&gt;http://www.moviemaze.de/filme/\1/\2&lt;/url&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes">&lt;a href=&quot;/filme/([0-9]+)/([^&quot;]*)&quot;&gt;&lt;b style=&quot;font-size:9pt;font-weight:bold;&quot;&gt;([^&lt;]*)&lt;/b&gt;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetSearchResults>
+
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <!--Title-->
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5+">
+ <expression trim="1" noclean="1">&lt;h1&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <!--Original Title-->
+ <RegExp input="$$1" output="&lt;originaltitle&gt;\1&lt;/originaltitle&gt;" dest="5+">
+ <expression>&lt;h2&gt;\(([^,]*)</expression>
+ </RegExp>
+ <!--Year Film-->
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>([0-9]+)\)&lt;/h2</expression>
+ </RegExp>
+ <!--MPAA Film-->
+ <RegExp input="$$2" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="\2" dest="2">
+ <expression trim="2">FSK([^&quot;]*)&quot;standard&quot; valign=&quot;top&quot;&gt;&lt;nobr&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <expression>[\t]\b(.*)\b</expression>
+ </RegExp>
+ <!--Director Film-->
+ <RegExp input="$$7" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <RegExp input="$$1" output="\2" dest="2">
+ <expression>Regie([^&quot;]*)&quot;standard_justify&quot;&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$2" output="\1" dest="7">
+ <expression>[\t]\b(.*)\b</expression>
+ </RegExp>
+ <expression repeat="yes">([^,]+)</expression>
+ </RegExp>
+ <!--Runtime Film-->
+ <RegExp input="$$2" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <RegExp input="$$1" output="\2" dest="2">
+ <expression>L.nge([^&quot;]*)&quot;standard&quot; valign=&quot;top&quot;&gt;&lt;nobr&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <expression>[\t]\b(.*)\b</expression>
+ </RegExp>
+ <!--URL to Thumbnail-->
+ <RegExp input="$$1" output="&lt;url function=&quot;GetThumbnailLink&quot;&gt;http://www.moviemaze.de/media/poster/\1/\2&lt;/url&gt;" dest="5+">
+ <expression>/media/poster/([0-9]+)/([^&quot;]*)</expression>
+ </RegExp>
+ <!--URL to Trailer-->
+ <RegExp conditional="trailer" input="$$1" output="&lt;url function=&quot;GetTrailerLink&quot;&gt;http://www.moviemaze.de/media/trailer/\1.html&lt;/url&gt;" dest="5+">
+ <expression>/media/trailer/([0-9]+,[a-zA-Z0-9\-]+).html. ti</expression>
+ </RegExp>
+ <!--URL to Google and Fanart-->
+ <RegExp conditional="fanart" input="$$8" output="&lt;url function=&quot;GetTMDBFanartByIMDBId&quot;&gt;http://www.google.com/search?q=site:imdb.com+moviemaze\1&lt;/url&gt;" dest="5+">
+ <RegExp input="$$1" output="&quot;\1&quot;" dest="7">
+ <expression>&lt;h2&gt;\(([^,]*)</expression>
+ </RegExp>
+ <RegExp input="$$7" output="+\1" dest="8+">
+ <expression repeat="yes">([^ ,]+)</expression>
+ </RegExp>
+ <expression></expression>
+ </RegExp>
+ <!--User rating-->
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;&lt;votes&gt;100&lt;/votes&gt;" dest="5+">
+ <expression trim="1" noclean="1">Wertung von ([0-9]+)%</expression>
+ </RegExp>
+ <!--Genre Film-->
+ <RegExp input="$$7" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <RegExp input="$$1" output="\2" dest="2">
+ <expression>Genre([^&quot;]*)&quot;standard&quot; valign=&quot;top&quot;&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$2" output="\1" dest="7">
+ <expression>[\t]\b(.*)\b</expression>
+ </RegExp>
+ <expression repeat="yes">([^, ]+)</expression>
+ </RegExp>
+ <!--Writer-->
+ <RegExp input="$$7" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="5+">
+ <RegExp input="$$1" output="\2" dest="2">
+ <expression trim="2">Drehbuch([^%]*)%&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$2" output="\1" dest="7">
+ <expression>[\t]\b(.*)\b</expression>
+ </RegExp>
+ <expression repeat="yes">([^,]+)</expression>
+ </RegExp>
+ <!--Plot-->
+ <RegExp input="$$1" output="&lt;plot&gt;\2&lt;/plot&gt;" dest="5+">
+ <expression trim="1">Inhalt&lt;/h3&gt;.([^&gt;]*)&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <!--Actors-->
+ <RegExp input="$$4" output="&lt;actor&gt;&lt;name&gt;\2&lt;/name&gt;&lt;role&gt;\5&lt;/role&gt;&lt;/actor&gt;" dest="5+">
+ <RegExp input="$$1" output="\2" dest="2">
+ <expression>Darsteller:([^%]*)%&gt;(.*?)&lt;/td</expression>
+ </RegExp>
+ <RegExp input="$$2" output="\1" dest="4">
+ <expression>[\t]\b(.*)\b</expression>
+ </RegExp>
+ <expression repeat="yes">(&lt;a href\="[^&gt;]*&gt;)?(.*?)(&lt;/a&gt;)?( \((.*?)\))?, </expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+
+ <!--Thumbnail-->
+ <GetThumbnailLink dest="5">
+ <RegExp input="$$2" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;&gt;&lt;details&gt;\1&lt;/details&gt;" dest="5+">
+ <RegExp input="$$1" output="&lt;thumb&gt;http://www.moviemaze.de/filme/\1/poster_lg\2.jpg&lt;/thumb&gt;" dest="2">
+ <expression repeat="yes">/([0-9]+)/poster([0-9]+)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetThumbnailLink>
+ <!--Trailer-->
+ <GetTrailerLink dest="5">
+ <RegExp input="$$2" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;&gt;&lt;details&gt;\1&lt;/details&gt;" dest="5+">
+ <RegExp input="$$1" output="&lt;trailer urlencoded=&quot;yes&quot;&gt;http://www.moviemaze.de/media/trailer/delivery/\1.mov&lt;/trailer&gt;" dest="2+">
+ <expression>delivery/([0-9]+/[a-z0-9]+/[0-9]+_trailer[0-9]+-de_640).mov</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;trailer urlencoded=&quot;yes&quot;&gt;http://www.moviemaze.de/media/trailer/delivery/\1.mov&lt;/trailer&gt;" dest="2+">
+ <expression>delivery/([0-9]+/[a-z0-9]+/[0-9]+_trailer[0-9]+-de_480).mov</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;trailer urlencoded=&quot;yes&quot;&gt;http://www.moviemaze.de/media/trailer/delivery/\1.mov&lt;/trailer&gt;" dest="2+">
+ <expression>delivery/([0-9]+/[a-z0-9]+/[0-9]+_trailer[0-9]+-de_384).mov</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;trailer urlencoded=&quot;yes&quot;&gt;http://www.moviemaze.de/media/trailer/delivery/\1.mov&lt;/trailer&gt;" dest="2+">
+ <expression>delivery/([0-9]+/[a-z0-9]+/[0-9]+_trailer[0-9]+-de_320).mov</expression>
+ </RegExp>
+ <expression clear="yes" noclean="1"></expression>
+ </RegExp>
+ </GetTrailerLink>
+</scraper>
diff --git a/system/scrapers/video/mtime.jpg b/system/scrapers/video/mtime.jpg
new file mode 100644
index 0000000000..80ebd7c2ec
--- /dev/null
+++ b/system/scrapers/video/mtime.jpg
Binary files differ
diff --git a/system/scrapers/video/mtime.xml b/system/scrapers/video/mtime.xml
new file mode 100644
index 0000000000..ae6fea8680
--- /dev/null
+++ b/system/scrapers/video/mtime.xml
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.1" date="2009-08-04" name="Mtime(Chinese)" content="movies" thumb="mtime.jpg" language="zh">
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Fanart&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;\1&lt;/url&gt;" dest="3">
+ <expression clear="yes" noclean="1">(http://www.mtime.com/movie/[0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateSearchUrl dest="3" SearchStringEncoding="gb2312">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.mtime.com/search/movie?\1&lt;/url&gt;" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url&gt;http://www.mtime.com/movie/\1/&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes" noclean="1">&lt;a id=&quot;highlight&quot; name=&quot;highlight&quot; href=&quot;/movie/([0-9]*)/&quot; target=&quot;_blank&quot; title=&quot;([^&quot;]*)&quot;&gt;</expression>
+ </RegExp>
+ <expression clear="yes" noclean="1"/>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$2" output="&lt;id&gt;\1&lt;/id&gt;" dest="5">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5+">
+ <expression trim="1" noclean="1">&lt;a href=&quot;/movie/[0-9]*/&quot; class=&quot;px28 bold hei c_000&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>href=&quot;/movie/section/year/([0-9]*)/&quot;</expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;url cache=&quot;$$2-details.html&quot; function=&quot;GetDetailsPage&quot;&gt;$$3details.html&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression trim="1">片长:&lt;/strong&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;url cache=&quot;$$2-rating.html&quot; function=&quot;GetRating&quot;&gt;$$3rating/summary.html&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes">href=&quot;/movie/section/genre/[^&gt;]*&gt;([^&lt;]*)&&nbsp</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>&lt;!-- 剧情介绍 --&gt;.*?&lt;p &gt;(.*?)\t&lt;/p&gt;</expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;url cache=&quot;$$2-fullcredits.html&quot; function=&quot;GetFullcredits&quot;&gt;$$3fullcredits.html&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;url cache=&quot;$$2-posters.html&quot; function=&quot;GetMtimePoster&quot;&gt;$$3posters_and_images/posters.html&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="fanart" input="$$2" output="&lt;url cache=&quot;$$2-fanart.html&quot; function=&quot;GetMtimeWallpapers&quot;&gt;$$3posters_and_images/wallpapers.html&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="fanart" input="$$2" output="&lt;url cache=&quot;$$2-fanart.html&quot; function=&quot;GetMtimeFanart&quot;&gt;$$3posters_and_images/stills.html&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+
+ <GetDetailsPage clearbuffers="no" dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;" dest="2">
+ <expression clear="yes">MPAAиЇ„зє§пјљ.*?&lt;li&gt;([^&lt;]*)&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;certification&gt;\1&lt;/certification&gt;" dest="2+">
+ <expression repeat="yes">href=&quot;/movie/section/certification/[^&quot;]*&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetailsPage>
+ <GetRating clearbuffers="no" dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;&lt;votes&gt;\2&lt;/votes&gt;" dest="2">
+ <expression clear="yes">е…ЁйѓЁдјље‘.*?class=&quot;score&quot;&gt;([0-9.]+)&lt;/span&gt;.*?class=&quot;vote&quot;&gt;([0-9]+)&lt;/span&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetRating>
+ <GetFullcredits clearbuffers="no" dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression clear="yes" noclean="1">жј”е‘ Actorпјљ(.*?)&lt;/ul&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;thumb&gt;\1.jpg&lt;/thumb&gt;&lt;name&gt;\2&lt;/name&gt;&lt;role&gt;\3&lt;/role&gt;&lt;/actor&gt;" dest="7">
+ <expression clear="yes" repeat="yes" noclean="1" trim="2,3">&lt;img alt=&quot;[^&quot;]*&quot; src=&quot;([^_]*)_22X22.jpg&quot;/&gt;&lt;/a&gt;&lt;a href=&quot;/person/[0-9]+/&quot;&gt;([^&lt;]*)&lt;/a&gt;(.*?)&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;actor&gt;\1&lt;role&gt;\2&lt;/role&gt;&lt;/actor&gt;" dest="2">
+ <expression clear="yes" repeat="yes" noclean="1,2">&lt;actor&gt;(.*?)&lt;role&gt;[^&lt;]*\.\.\.\.([^&lt;]*)&lt;/role&gt;&lt;/actor&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression clear="yes" noclean="1">еЇјжј” Directorпјљ(.*?)&lt;/ul&gt;</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;director&gt;\1&lt;/director&gt;" dest="2+">
+ <expression repeat="no">&lt;a href=&quot;/person/[0-9]+/&quot;&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression clear="yes" noclean="1">编剧 Writer:(.*?)&lt;/ul&gt;</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="2+">
+ <expression repeat="no">&lt;a href=&quot;/person/[0-9]+/&quot;&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetFullcredits>
+ <GetMtimePoster dest="5">
+ <RegExp input="$$6" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb&gt;\1.jpg&lt;/thumb&gt;" dest="6">
+ <expression clear="yes" repeat="yes" noclean="1">src=&quot;(http://img1.mtime.com/[^_]*)_[0-9X]+.jpg&quot;/&gt;&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetMtimePoster>
+ <GetMtimeWallpapers clearbuffers="no" dest="6">
+ <RegExp input="$$1" output="&lt;thumb preview=&quot;\1.jpg&quot;&gt;\1_o.jpg&lt;/thumb&gt;" dest="10">
+ <expression clear="yes" repeat="yes" noclean="1">src=&quot;http://img1.mtime.com/([^_]*)(_[0-9X]+).jpg&quot;/&gt;&lt;/a&gt;</expression>
+ </RegExp>
+ </GetMtimeWallpapers>
+ <GetMtimeFanart dest="5">
+ <RegExp input="$$10$$11" output="&lt;details&gt;&lt;fanart url=&quot;http://img1.mtime.com/&quot;&gt;\1&lt;/fanart&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb preview=&quot;\1.jpg&quot;&gt;\1_o.jpg&lt;/thumb&gt;" dest="11">
+ <expression clear="yes" repeat="yes" noclean="1">src=&quot;http://img1.mtime.com/([^_]*)(_[0-9X]+).jpg&quot;/&gt;&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetMtimeFanart>
+</scraper>
diff --git a/system/scrapers/video/mtv.png b/system/scrapers/video/mtv.png
new file mode 100644
index 0000000000..dcb14290b7
--- /dev/null
+++ b/system/scrapers/video/mtv.png
Binary files differ
diff --git a/system/scrapers/video/mtv.xml b/system/scrapers/video/mtv.xml
new file mode 100644
index 0000000000..5d85b9de5c
--- /dev/null
+++ b/system/scrapers/video/mtv.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.0" date="2009-05-22" name="MTV" content="musicvideos" thumb="mtv.png" language="en">
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://api.mtvnservices.com/1/video/search/?term=\1&lt;/url&gt;" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\1 - \2&lt;/title&gt;&lt;url&gt;\4&lt;/url&gt;&lt;/entity&gt;" dest="5">
+ <expression noclean="1" repeat="yes">&lt;entry&gt;.*?&lt;content&gt;(.*?) \| (.*?) \| (.*?)&lt;/content&gt;.*?media:player url=&quot;([^&quot;]*)&quot;/&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression trim="1" noclean="1">&lt;meta name=&quot;mtv_vt&quot; content=&quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;artist&gt;\1&lt;/artist&gt;" dest="5+">
+ <expression trim="1" noclean="1">&lt;meta name=&quot;mtv_an&quot; content=&quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;album&gt;\1&lt;/album&gt;" dest="5+">
+ <expression trim="1" noclean="1">&lt;meta name=&quot;mtv_at&quot; content=&quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="5+">
+ <expression trim="1" noclean="1">&lt;strong&gt;Label&lt;/strong&gt; ([^&lt;]*)&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>&lt;meta name=&quot;content_create_date&quot; content=&quot;([0-9]*)-[^&quot;]*&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <expression trim="1" noclean="1">&lt;meta name=&quot;mtv_vd&quot; content=&quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;http://www.mtv.com\2.jpg&lt;/thumb&gt;" dest="5+">
+ <expression noclean="1">&quot;thumbnail&quot;([^&quot;]*)content=&quot;([^&quot;]*)\.jpg</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+</scraper>
diff --git a/system/scrapers/video/musicvideos.xml b/system/scrapers/video/musicvideos.xml
new file mode 100644
index 0000000000..e778741760
--- /dev/null
+++ b/system/scrapers/video/musicvideos.xml
@@ -0,0 +1,37 @@
+п»ї<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.0" date="2009-05-22" name="NFO Scraper" content="musicvideos" thumb="mvids.gif" language="en">
+ <NfoScrape dest="3">
+ <RegExp input="$$5" output="&lt;musicvideo&gt;\1&lt;/musicvideo&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression trim="1">[Tt]itle[ ]*:&lt;? ([0-9a-zA-Z':\. &amp;]+)[^0-9a-zA-Z':\. &amp;]</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;artist&gt;\1&lt;/artist&gt;" dest="5+">
+ <expression trim="1">[Aa]rtist[ ]*:&lt;? ([0-9a-zA-Z':\. &amp;]+)[^0-9a-zA-Z':\. &amp;]</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression trim="1">[Gg]enre[ ]*:&lt;? ([0-9a-zA-Z':\. &amp;]+)[^0-9a-zA-Z':\. &amp;]</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>[Yy]ear[ ]*:&lt;? ([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>[Dd]ate[ ]*:&lt;? [0-9][0-9][/\.][0-9][0-9][/\.]([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression>[Rr]untime[ ]*:&lt;? ([:0-9]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression>[Ll]ength[ ]*:&lt;? ([:0-9]+)</expression>
+ </RegExp>
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
+ </NfoScrape>
+ <FileNameScrape dest="3">
+ <RegExp input="$$1" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&lt;musicvideo&gt;&lt;artist&gt;\1&lt;/artist&gt;&lt;title&gt;\2&lt;/title&gt;&lt;year&gt;\3&lt;/year&gt;&lt;/musicvideo&gt;" dest="3">
+ <expression>[\\/]([^\\/]+) - ([^\\/]+) - ([0-9]{4})[^\\/]*</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&lt;musicvideo&gt;&lt;artist&gt;\1&lt;/artist&gt;&lt;title&gt;\2&lt;/title&gt;&lt;/musicvideo&gt;" dest="3+">
+ <expression>[\\/]([^\\/]+) - ([^\\/]+)[^\\/]*</expression>
+ </RegExp>
+ </FileNameScrape>
+</scraper>
diff --git a/system/scrapers/video/mymoviesdk.png b/system/scrapers/video/mymoviesdk.png
new file mode 100644
index 0000000000..5771b4596d
--- /dev/null
+++ b/system/scrapers/video/mymoviesdk.png
Binary files differ
diff --git a/system/scrapers/video/mymoviesdk.xml b/system/scrapers/video/mymoviesdk.xml
new file mode 100644
index 0000000000..d8b0ffda1a
--- /dev/null
+++ b/system/scrapers/video/mymoviesdk.xml
@@ -0,0 +1,188 @@
+п»ї<?xml version="1.0" encoding="utf-8"?>
+<scraper framework="1.1" date="2009-08-11" name="MyMovies.dk" content="movies" thumb="mymoviesdk.png" language="en" requiressettings="true">
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <!--Username-->
+ <RegExp input="$$1" output="&lt;setting label=&quot;Username&quot; type=&quot;text&quot; id=&quot;username&quot; default=&quot;&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <!--Password-->
+ <RegExp input="$$1" output="&lt;setting label=&quot;Password&quot; type=&quot;text&quot; option=&quot;hidden&quot; id=&quot;password&quot; default=&quot;&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <!--- -->
+ <RegExp input="$$1" output="&lt;setting type=&quot;sep&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <!--Fanart-->
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Fanart&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <!--Trailer-->
+ <RegExp input="$$1" output="&lt;setting label=&quot;Preferred trailer bitrate&quot; type=&quot;labelenum&quot; values=&quot;2048|1024|512|256|128&quot; id=&quot;trailerbitrate&quot; default=&quot;2048&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <!--Preferred language-->
+ <RegExp input="$$1" output="&lt;setting label=&quot;Preferred language&quot; type=&quot;labelenum&quot; values=&quot;Arabic|Bulgarian|Cantonese|Mandarin|Czech|Croatian|Danish|Dutch|English|Estonian|Faroese|Farsi|Finnish|Flemish|French|German|Greek|Hebrew|Hindi|Hungarian|Icelandic|Indonesian|Italian|Japanese|Korean|Lithuanian|Norwegian|Polish|Portuguese|Romanian|Russian|Serbian|Slovakian|Slovene|Spanish|Swedish|Tagalog|Thai|Turkish|Malay|Latvian|Ukrainian|Tamil|Catalan|Telugu|Malayalam|Kannada|Bengali|Serbo-Croatian|Gujarati|Esperanto|Vietnamese|Kazakh|Ancient Greek|Mandar|Braj|Macedonian|Zulu|Twi|VolapГјk|Albanian|Khmer|Basque&quot; id=&quot;language&quot; default=&quot;English&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <!--Include adult movies-->
+ <RegExp input="$$1" output="&lt;setting label=&quot;Include adult movies&quot; type=&quot;bool&quot; id=&quot;includeadult&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting type=&quot;sep&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;https://api.mymovies.dk/Default.aspx?command=SearchMovieByTitle&amp;amp;title=\1&amp;amp;username=$INFO[username]&amp;amp;password=$INFO[password]&amp;amp;PrimaryLanguage=$INFO[language]&amp;amp;includeadult=$INFO[includeadult]&amp;amp;locale=1033&lt;/url&gt;" dest="3">
+ <RegExp input="$$2" output="%20(\1)" dest="4">
+ <expression clear="yes">(.+)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+
+ <GetSearchResults dest="8">
+ <RegExp input="$$3" output="&lt;results sorted=&quot;Yes&quot;&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;year&gt;\3&lt;/year&gt;&lt;id&gt;\1&lt;/id&gt;&lt;url&gt;https://api.mymovies.dk/Default.aspx?command=LoadMovieById&amp;amp;titleid=\1&amp;amp;username=$INFO[username]&amp;amp;password=$INFO[password]&amp;amp;PrimaryLanguage=$INFO[language]&amp;amp;maxtrailerbitrate=$INFO[trailerbitrate]&amp;amp;locale=1033&amp;amp;client=xbmcbased&lt;/url&gt;&lt;/entity&gt;" dest="3">
+ <expression repeat="yes">id="(.*?)".*? title="(.*?)"[^&lt;]*year="(.*?)" thumb</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ <RegExp input="$$4" output="&lt;error&gt;\1&lt;/error&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;title&gt;Error returned from MyMovies.dk&lt;/title&gt;&lt;message&gt;\1&lt;/message&gt;" dest="4">
+ <expression repeat="no">&lt;response status="failed"&gt;(.*?)&lt;/response&gt;</expression>
+ </RegExp>
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
+ </GetSearchResults>
+
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;https://api.mymovies.dk/Default.aspx?command=LoadMovieByIMDBId&amp;imdbid=tt\2&amp;username=$INFO[username]&amp;password=$INFO[password]&amp;PrimaryLanguage=$INFO[language]&amp;includeadult=$INFO[includeadult]&amp;maxtrailerbitrate=$INFO[trailerbitrate]&amp;locale=1033&lt;/url&gt;" dest="3">
+ <expression>(imdb.com/title/tt)([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url&gt;https://api.mymovies.dk/Default.aspx?command=LoadMovieByIMDBId&amp;imdbid=tt\2&amp;username=$INFO[username]&amp;password=$INFO[password]&amp;PrimaryLanguage=$INFO[language]&amp;includeadult=$INFO[includeadult]&amp;maxtrailerbitrate=$INFO[trailerbitrate]&amp;locale=1033&lt;/url&gt;" dest="3+">
+ <expression>(imdb.com/)Title\?([0-9]+)</expression>
+ </RegExp>
+ </NfoUrl>
+
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <!--Title-->
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression>&lt;LocalTitle&gt;([^&lt;]*)&lt;/LocalTitle&gt;</expression>
+ </RegExp>
+ <!--SortTitle-->
+ <RegExp input="$$1" output="&lt;sorttitle&gt;\1&lt;/sorttitle&gt;" dest="5+">
+ <expression>&lt;SortTitle&gt;([^&lt;]*)&lt;/SortTitle&gt;</expression>
+ </RegExp>
+ <!--Year-->
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>&lt;ProductionYear&gt;([0-9]+)&lt;/ProductionYear&gt;</expression>
+ </RegExp>
+ <!--Thumb-->
+ <RegExp input="$$1" output="&lt;thumb preview=&quot;\1&quot;&gt;\2&lt;/thumb&gt;" dest="5+">
+ <expression repeat="yes">&lt;Poster FileThumb="([^"]*)" File="([^"]*)" Hash=</expression>
+ </RegExp>
+ <!--IMDB-->
+ <RegExp input="$$1" output="&lt;id&gt;\1&lt;/id&gt;" dest="5+">
+ <expression>&lt;IMDB&gt;([^&lt;]*)&lt;/IMDB&gt;</expression>
+ </RegExp>
+ <!--Runtime-->
+ <RegExp input="$$1" output="&lt;runtime&gt;\1 min&lt;/runtime&gt;" dest="5+">
+ <expression>&lt;RunningTime&gt;([^&lt;]*)&lt;/RunningTime&gt;</expression>
+ </RegExp>
+ <!--Rating-->
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="5+">
+ <expression>&lt;Rating&gt;([^&lt;]*)&lt;/Rating&gt;</expression>
+ </RegExp>
+ <!--Votes-->
+ <RegExp input="$$1" output="&lt;votes&gt;\1&lt;/votes&gt;" dest="5+">
+ <expression>&lt;RatingVotes&gt;([^&lt;]*)&lt;/RatingVotes&gt;</expression>
+ </RegExp>
+ <!--Studio-->
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="5+">
+ <expression repeat="yes">&lt;Studio&gt;([^&lt;]*)&lt;/Studio&gt;</expression>
+ </RegExp>
+ <!--Genre-->
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes">&lt;Genre&gt;([^&lt;]*)&lt;/Genre&gt;</expression>
+ </RegExp>
+ <!--Plot-->
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>&lt;Description&gt;[^&lt;]*&lt;!\[CDATA\[([^&lt;]*)\]\][^&lt;]*&lt;/Description&gt;</expression>
+ </RegExp>
+ <!--Plot Outline-->
+ <RegExp input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;" dest="5+">
+ <expression>&lt;Overview&gt;([^&lt;]*)&lt;/Overview&gt;</expression>
+ </RegExp>
+ <!--MPAA-->
+ <RegExp input="$$4" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;" dest="5+">
+ <RegExp input="$$1" output="None" dest="4">
+ <expression>&lt;ParentalRating[^.]*?&lt;Value&gt;-1&lt;/Value&gt;[^.]*?&lt;Description&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="Unrated" dest="4">
+ <expression>&lt;ParentalRating[^.]*?&lt;Value&gt;0&lt;/Value&gt;[^.]*?&lt;Description&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="G" dest="4">
+ <expression>&lt;ParentalRating[^.]*?&lt;Value&gt;(1|2)&lt;/Value&gt;[^.]*?&lt;Description&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="PG" dest="4">
+ <expression>&lt;ParentalRating[^.]*?&lt;Value&gt;3&lt;/Value&gt;[^.]*?&lt;Description&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="PG-13" dest="4">
+ <expression>&lt;ParentalRating[^.]*?&lt;Value&gt;(4|5)&lt;/Value&gt;[^.]*?&lt;Description&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="R" dest="4">
+ <expression>&lt;ParentalRating[^.]*?&lt;Value&gt;6&lt;/Value&gt;[^.]*?&lt;Description&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="NC-17" dest="4">
+ <expression>&lt;ParentalRating[^.]*?&lt;Value&gt;7&lt;/Value&gt;[^.]*?&lt;Description&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="NC-17" dest="4">
+ <expression>&lt;ParentalRating[^.]*?&lt;Value&gt;8&lt;/Value&gt;[^.]*?&lt;Description&gt;</expression>
+ </RegExp>
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
+ <!--Tagline-->
+ <RegExp input="$$1" output="&lt;tagline&gt;\1&lt;/tagline&gt;" dest="5+">
+ <expression>&lt;TagLine&gt;([^&lt;]*)&lt;/TagLine&gt;</expression>
+ </RegExp>
+ <!--Director-->
+ <RegExp input="$$1" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <expression repeat="yes">&lt;Person Type="2"[^$]*?&lt;Name&gt;([^&lt;]*)&lt;/Name&gt;</expression>
+ </RegExp>
+ <!--Writer-->
+ <RegExp input="$$1" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="5+">
+ <expression repeat="yes">&lt;Person Type="3"[^$]*?&lt;Name&gt;([^&lt;]*)&lt;/Name&gt;</expression>
+ </RegExp>
+ <!--Actor-->
+ <RegExp input="$$1" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\2&lt;/role&gt;&lt;/actor&gt;" dest="5+">
+ <expression repeat="yes">&lt;Person Type="1"[^.]*?&lt;Photo /&gt;[^.]*?&lt;Name&gt;([^&lt;]*)&lt;/Name&gt;[^.]*?&lt;Role&gt;([^&lt;]*)&lt;/Role&gt;</expression>
+ </RegExp>
+ <!--Actor with thumb-->
+ <RegExp input="$$1" output="&lt;actor&gt;&lt;thumb&gt;\1&lt;/thumb&gt;&lt;name&gt;\2&lt;/name&gt;&lt;role&gt;\3&lt;/role&gt;&lt;/actor&gt;" dest="5+">
+ <expression repeat="yes">&lt;Person Type="1"[^.]*?&lt;Photo&gt;([^&lt;]*)&lt;/Photo&gt;[^.]*?&lt;Name&gt;([^&lt;]*)&lt;/Name&gt;[^.]*?&lt;Role&gt;([^&lt;]*)&lt;/Role&gt;</expression>
+ </RegExp>
+ <!--Fanart-->
+ <RegExp conditional="fanart" input="$$4" output="&lt;fanart&gt;\1&lt;/fanart&gt;" dest="5+">
+ <RegExp input="$$1" output="&lt;thumb preview=&quot;\1&quot; dim=&quot;1920x1080&quot;&gt;\2&lt;/thumb&gt;" dest="4">
+ <expression repeat="yes">FileThumb="([^"]*)" F[^&lt;]*File1080P="([^"]*)" Hash1080p="[^"]+"</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb preview=&quot;\1&quot; dim=&quot;1280x720&quot;&gt;\2&lt;/thumb&gt;" dest="4+">
+ <expression repeat="yes">FileThumb="([^"]*)" File720P="([^"]*)" Hash720p[^&lt;]*File1080P=""</expression>
+ </RegExp>
+ <expression noclean="1">(.+)</expression>
+ </RegExp>
+ <!--Trailer - filmtrailer.com-->
+ <RegExp input="$$1" output="&lt;trailer&gt;\1&lt;/trailer&gt;" dest="5+">
+ <expression>&lt;Trailer[^&gt;]*&gt;([^&lt;]*)&lt;/Trailer&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+</scraper>
diff --git a/system/scrapers/video/naver.png b/system/scrapers/video/naver.png
new file mode 100644
index 0000000000..1dd4655c2b
--- /dev/null
+++ b/system/scrapers/video/naver.png
Binary files differ
diff --git a/system/scrapers/video/naver.xml b/system/scrapers/video/naver.xml
new file mode 100644
index 0000000000..f72b5c41b8
--- /dev/null
+++ b/system/scrapers/video/naver.xml
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.1" date="2009-08-08" name="NAVER (Korean)" content="movies" thumb="naver.png" language="ko">
+ <include>common/tmdb.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;БЦї¬№иїм/°ўє»/Б¦АЫ»зїЎ ґлЗС »ујјБ¤єё&quot; type=&quot;bool&quot; id=&quot;EnableDetail&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;ЖчЅєЕН&quot; type=&quot;bool&quot; id=&quot;EnableThumbs&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;ЖтБЎ ЕхЗҐАЪјц&quot; type=&quot;bool&quot; id=&quot;EnableVoteNum&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;ЖТѕЖЖ®(°нИ­Бъ)&quot; type=&quot;bool&quot; id=&quot;EnableFanArt&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://movie.naver.com/movie/bi/mi/basic.nhn?code=\1&lt;/url&gt;" dest="3">
+ <expression>movie\.naver\.com[^\?]*\?code=([0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+ <CreateSearchUrl dest="3" SearchStringEncoding="EUC-KR">
+ <RegExp input="$$1" output="http://movie.naver.com/movie/search/result.nhn?section=movie&amp;query=\1&amp;sort=3" dest="3">
+ <expression noclean="1"/>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;EUC-KR&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2 (\3) &lt;/title&gt;&lt;url&gt;http://movie.naver.com/movie/bi/mi/basic.nhn?code=\1&lt;/url&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes">&lt;dt&gt;&lt;a href=&quot;/movie/bi/mi/basic.nhn\?code=([0-9]*)&quot;&gt;(.[^&quot;]*)&quot;point&quot;&gt;[^\?]*\?year=([0-9]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails dest="3">
+ <RegExp input="$$8" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <!-- Titles, year !-->
+ <RegExp input="$$1" output="&lt;title&gt;\1 (\2, \3)&lt;/title&gt;&lt;originaltitle&gt;\2&lt;/originaltitle&gt;&lt;year&gt;\3&lt;/year&gt;" dest="8">
+ <expression trim="1" noclean="1">&quot;&amp;main_title=&quot;\+encodeURIComponent\(&quot;(.[^&quot;]*)&quot;\)\+&quot;&amp;sub_title=&quot;\+encodeURIComponent\(&quot;(.[^\,]*)\, ([0-9]*)&quot;\)</expression>
+ </RegExp>
+ <!-- Director's names !-->
+ <RegExp input="$$7" output="&lt;director&gt;\1&lt;/director&gt;" dest="8+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">db_htype_1_text_3\.gif&quot;(.*)db_htype_1_text_4\.gif&quot;</expression>
+ </RegExp>
+ <expression noclean="1" repeat="yes">&lt;a[^&gt;]*&gt;(.[^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <!-- Actors !-->
+ <RegExp conditional="!EnableDetail" input="$$7" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\2&lt;/role&gt;&lt;/actor&gt;" dest="8+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">db_htype_1_text_4\.gif&quot;(.*)&quot;more_inline&quot;</expression>
+ </RegExp>
+ <expression noclean="1" repeat="yes">&lt;a[^&gt;]*&gt;(.[^&lt;]*)&lt;/a&gt;\((.[^\)]*)\)</expression>
+ </RegExp>
+ <!-- MPAA !-->
+ <RegExp input="$$1" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;" dest="8+">
+ <expression noclean="1" repeat="yes">&lt;em&gt;[^&lt;]*&lt;/em&gt; &lt;a[^&gt;]*&gt;(.[^&lt;]*)&lt;</expression>
+ </RegExp>
+ <!-- Plot !-->
+ <RegExp input="$$1" output="&lt;plot&gt;\1\2&lt;/plot&gt;" dest="8+">
+ <expression>&lt;p class=&quot;c_ff4200&quot;&gt;(.[^&lt;]*)&lt;/p&gt;[^&lt;]*&lt;p&gt;(.*)&lt;/p&gt;[^&lt;]*&lt;ul class=&quot;other&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="8+">
+ <expression>&lt;p class=&quot;c_ff4200&quot;&gt;&lt;/p&gt;[^&lt;]*&lt;p&gt;(.*)&lt;/p&gt;[^&lt;]*&lt;ul class=&quot;other&quot;</expression>
+ </RegExp>
+ <!-- Thumbnail !-->
+ <RegExp conditional="!EnableThumbs" input="$$1" output="&lt;thumb&gt;&lt;url&gt;\1&lt;/url&gt;&lt;/thumb&gt;" dest="8+">
+ <expression>&lt;div class=&quot;poster&quot;&gt;[^\(]*\(&apos;([^&apos;]*)&apos;</expression>
+ </RegExp>
+ <!-- Premiered !-->
+ <RegExp input="$$1" output="&lt;premiered&gt;\1.\2&lt;/premiered&gt;" dest="8+">
+ <expression noclean="1">&gt;[^&lt;]*&lt;/font&gt; &lt;a[^&gt;]*&gt;([0-9]*)&lt;/a&gt;\.&lt;[^&gt;]*&gt;(.[^&lt;]*)&lt;</expression>
+ </RegExp>
+ <!-- Genres !-->
+ <RegExp input="$$7" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="8+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">db_htype_1_text_2\.gif&quot;(.*)nhn\?nation</expression>
+ </RegExp>
+ <expression noclean="1" repeat="yes">nhn\?genre[^&gt;]*&gt;(.[^&lt;]*)&lt;</expression>
+ </RegExp>
+ <!-- Runtime !-->
+ <RegExp input="$$1" output="&lt;runtime&gt;\1 minute&lt;/runtime&gt;" dest="8+">
+ <expression noclean="1">class=&apos;ls0&apos;&gt;([0-9]*)&lt;</expression>
+ </RegExp>
+ <!-- User rating !-->
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="8+">
+ <expression>&quot;&amp;star_point=([0-9]\.+[0-9]*)&quot;\;</expression>
+ </RegExp>
+ <!-- Tag Line !-->
+ <RegExp input="$$1" output="&lt;tagline&gt;\1&lt;/tagline&gt;" dest="8+">
+ <expression noclean="1">&lt;p class=&quot;c_ff4200&quot;&gt;(.[^&lt;]*)&lt;/p&gt;</expression>
+ </RegExp>
+ <!-- Detail !-->
+ <RegExp conditional="EnableDetail" input="$$1" output="&lt;url function=&quot;GetNAVERDetail&quot;&gt;http://movie.naver.com/movie/bi/mi/detail.nhn?code=\1&lt;/url&gt;" dest="8+">
+ <expression noclean="1">&lt;a href=&quot;/movie/bi/mi/photo.nhn\?code=([0-9]*)&quot;</expression>
+ </RegExp>
+ <!-- Thumbs !-->
+ <RegExp conditional="EnableThumbs" input="$$1" output="&lt;url function=&quot;GetNAVERPhoto&quot;&gt;http://movie.naver.com/movie/bi/mi/photo.nhn?code=\1&lt;/url&gt;" dest="8+">
+ <expression noclean="1">&lt;a href=&quot;/movie/bi/mi/photo.nhn\?code=([0-9]*)&quot;</expression>
+ </RegExp>
+ <!-- Votes !-->
+ <RegExp conditional="EnableVoteNum" input="$$1" output="&lt;url function=&quot;GetNAVERVote&quot;&gt;http://movie.naver.com/movie/bi/mi/point.nhn?code=\1&lt;/url&gt;" dest="8+">
+ <expression noclean="1">&lt;a href=&quot;/movie/bi/mi/photo.nhn\?code=([0-9]*)&quot;</expression>
+ </RegExp>
+ <!-- FanArts !-->
+ <RegExp conditional="EnableFanArt" input="$$5" output="&lt;url function=&quot;GetTMDBFanartByIMDBId&quot;&gt;http://api.themoviedb.org/2.0/Movie.search?title=\1&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="8+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1" clear="yes">&quot;&amp;sub_title=&quot;\+encodeURIComponent\(&quot;([^\,]*)\, ([0-9]*)&quot;\)</expression>
+ </RegExp>
+ <RegExp input="$$7" output="+\1" dest="5">
+ <expression repeat="yes">([^ ,]+)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ <!-- FanArts !-->
+ <RegExp conditional="EnableFanArt" input="$$1" output="&lt;url function=&quot;GetNAVERFanart&quot;&gt;http://movie.naver.com/movie/bi/mi/photo.nhn?code=\1&lt;/url&gt;" dest="8+">
+ <expression noclean="1">&lt;a href=&quot;/movie/bi/mi/photo.nhn\?code=([0-9]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetDetails>
+ <GetNAVERPhoto dest="8">
+ <RegExp input="$$9" output="&lt;details&gt;\1&lt;/details&gt;" dest="8">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">box_story_1 mt_10&quot;&gt;(.*)btn_dbreport\.gif</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;thumb preview=&quot;http://imgmovie.naver.com/mdi/mit120/\1&quot;&gt;http://imgmovie.naver.com/mdi/mit500/\1&lt;/thumb&gt;" dest="9">
+ <expression noclean="1" repeat="yes">&quot;&gt;&lt;img src=&quot;http://imgmovie.naver.com/mdi/mit120/(.[^&quot;]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetNAVERPhoto>
+ <GetNAVERVote dest="8">
+ <RegExp input="$$9" output="&lt;details&gt;\1&lt;/details&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;votes&gt;\1&lt;/votes&gt;" dest="9">
+ <expression noclean="1" trim="1">&lt;p class=&quot;join&quot;&gt;[^&gt;]*&gt;(.[^&lt;]*)&lt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetNAVERVote>
+ <GetNAVERDetail dest="8">
+ <RegExp input="$$9" output="&lt;details&gt;;\1&lt;/details&gt;" dest="8">
+ <!-- studio !-->
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="9">
+ <expression noclean="1" repeat="yes">&lt;a href=&quot;/movie/bi/ci/filmo\.nhn\?code=[0-9]*&quot;&gt;(.[^&lt;]*)&lt;</expression>
+ </RegExp>
+ <!-- Actors !-->
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">id=&quot;cast_1&quot;(.*)id=&quot;cast_2&quot;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;actor&gt;&lt;name&gt;\2&lt;/name&gt;&lt;role&gt;\3&lt;/role&gt;&lt;thumb&gt;\1&lt;/thumb&gt;&lt;/actor&gt;" dest="9+">
+ <expression noclean="1" repeat="yes">class=&quot;thumb&quot;&gt;&lt;a[^&lt;]*&lt;img src=&quot;(.[^&quot;]*)&quot;[^&lt;]*&lt;/a&gt;&lt;/td&gt;[^&gt;]*&gt;&lt;a[^&gt;]*&gt;(.[^&lt;]*)&lt;/a&gt; &lt;[^&lt;]*&lt;/span&gt;&lt;br&gt;(.[^&lt;]*)&lt;/th&gt;</expression>
+ </RegExp>
+ <!-- writer !-->
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">&lt;h6&gt;°ўє»&lt;/h6&gt;(.*)id=&quot;staff_2&quot;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="9+">
+ <expression noclean="1" repeat="yes">&lt;a href=&quot;/movie/bi/pi/basic.nhn\?code=[0-9]*&quot;&gt;(.[^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetNAVERDetail>
+ <GetNAVERFanart clearbuffers="no" dest="8">
+ <RegExp input="$$10$$11" output="&lt;details&gt;&lt;fanart&gt;\1&lt;/fanart&gt;&lt;/details&gt;" dest="8">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression noclean="1">box_story_1 mt_10&quot;&gt;(.*)btn_dbreport\.gif</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;thumb preview=&quot;http://imgmovie.naver.com/mdi/mit120/\1&quot;&gt;http://imgmovie.naver.com/mdi/mi/\1&lt;/thumb&gt;" dest="11">
+ <expression noclean="1" repeat="yes" clear="yes">&quot;&gt;&lt;img src=&quot;http://imgmovie.naver.com/mdi/mit120/(.[^&quot;]*)&quot;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetNAVERFanart>
+</scraper>
+
diff --git a/system/scrapers/video/ofdb.png b/system/scrapers/video/ofdb.png
new file mode 100644
index 0000000000..9b7ecbad4c
--- /dev/null
+++ b/system/scrapers/video/ofdb.png
Binary files differ
diff --git a/system/scrapers/video/ofdb.xml b/system/scrapers/video/ofdb.xml
new file mode 100644
index 0000000000..96da60f805
--- /dev/null
+++ b/system/scrapers/video/ofdb.xml
@@ -0,0 +1,261 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<scraper framework="1.1" date="2009-08-10" name="OFDb" content="movies" thumb="ofdb.png" language="de">
+ <include>common/tmdb.xml</include>
+ <include>common/movieposterdb.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Fanart&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;MoviePosterDB&quot; type=&quot;bool&quot; id=&quot;movieposterdb&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression />
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Trailer&quot; type=&quot;bool&quot; id=&quot;trailer&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Groesse der Darsteller Bilder&quot; type=&quot;labelenum&quot; values=&quot;192|256|384|512|1024&quot; id=&quot;imdbscale&quot; default=&quot;512&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;\1\2,\3&lt;/url&gt;" dest="3">
+ <expression clear="yes" noclean="1">(http://www.ofdb.de/film/)([0-9]*),(.*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetByIMDBId&quot;&gt;http://www.ofdb.de/view.php?SText=\2&amp;amp;Kat=IMDb&amp;amp;page=suchergebnis&amp;amp;sourceid=mozilla-search&lt;/url&gt;" dest="3+">
+ <expression>(imdb.com/)Title\?([0-9]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetByIMDBId&quot;&gt;http://www.ofdb.de/view.php?SText=\2&amp;amp;Kat=IMDb&amp;amp;page=suchergebnis&amp;amp;sourceid=mozilla-search&lt;/url&gt;" dest="3+">
+ <expression>(imdb.com/title/tt)([0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+
+ <GetByIMDBId dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.ofdb.de/film/\1,&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;" dest="3+">
+ <expression repeat="yes" noclean="1">&quot;film/([0-9]*),</expression>
+ </RegExp>
+ </GetByIMDBId>
+
+
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="http://www.ofdb.de/view.php?SText=\1&amp;Kat=Titel&amp;page=suchergebnis&amp;sourceid=mozilla-search" dest="3">
+ <expression noclean="1">([^\(]+)</expression>
+ </RegExp>
+ </CreateSearchUrl>
+
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2 (\4) | \3&lt;/title&gt;&lt;year&gt;\4&lt;/year&gt;&lt;url cache=&quot;\1.html&quot;&gt;http://www.ofdb.de/film/\1,&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes" noclean="1">&lt;a href=.[^0-9]+([0-9]+)[^ ]+ onmouseover=.Tip..&lt;[^&gt;]+&gt;[^&gt;]+&gt;([^&lt;]+)&lt;font size=.1.&gt; . ([^&lt;]+)&lt;/font&gt; \(([0-9]+)\)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <!--Title -->
+ <RegExp input="$$6" output="\1" dest="5+">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="6">
+ <expression trim="1">&lt;td width=&quot;99.&quot;&gt;&lt;h2&gt;&lt;font face=&quot;Arial,Helvetica,sans-serif&quot; size=&quot;3&quot;&gt;&lt;b&gt;([^&lt;]+)&lt;/b&gt;&lt;/font&gt;&lt;/h2&gt;&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;title&gt;\2 \1&lt;/title&gt;" dest="6">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression trim="1">&lt;td width=&quot;99.&quot;&gt;&lt;h2&gt;&lt;font face=&quot;Arial,Helvetica,sans-serif&quot; size=&quot;3&quot;&gt;&lt;b&gt;([^&lt;]+)&lt;/b&gt;&lt;/font&gt;&lt;/h2&gt;&lt;/td&gt;</expression>
+ </RegExp>
+ <expression>(.*), (Die|Der|Das|The)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!--Original Title -->
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression noclean="1">class=&quot;Normal&quot;&gt;Originaltitel(.*)class=&quot;Normal&quot;&gt;Herstellungsland</expression>
+ </RegExp>
+
+ <RegExp input="$$7" output="\1" dest="5+">
+ <RegExp input="$$8" output="&lt;originaltitle&gt;\1&lt;/originaltitle&gt;" dest="7">
+ <expression>&lt;b&gt;([^&gt;]+)&lt;/b&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;originaltitle&gt;\2 \1&lt;/originaltitle&gt;" dest="7">
+ <RegExp input="$$8" output="\1" dest="6">
+ <expression noclean="1">&lt;b&gt;([^&gt;]+)&lt;/b&gt;</expression>
+ </RegExp>
+ <expression>(.*), (Die|Der|Das|The)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!--Year -->
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>view.php\?page=blaettern&amp;Kat=Jahr&amp;Text=([0-9]+)</expression>
+ </RegExp>
+
+ <!--Director-->
+ <RegExp input="$$9" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">class=&quot;Normal&quot;&gt;Regie(.*)class=&quot;Normal&quot;&gt;Darsteller</expression>
+ </RegExp>
+ <expression repeat="yes">Name=[^&gt;]*&gt;([^&lt;]+)</expression>
+ </RegExp>
+
+ <!--Plot outline -->
+ <RegExp input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>&lt;b&gt;Inhalt:&lt;/b&gt;([^&lt;]+)</expression>
+ </RegExp>
+
+ <!--Genre-->
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes">view.php\?page=genre&amp;Genre=[^&quot;]+&quot;&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+
+ <!--Rating-->
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="5+">
+ <expression>Note: ([0-9\.]+)</expression>
+ </RegExp>
+
+ <!--Votes-->
+ <RegExp input="$$1" output="&lt;votes&gt;\1&lt;/votes&gt;" dest="5+">
+ <expression>Stimmen: ([0-9]+)</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;" dest="5+">
+ <expression>Freigabe: ([^&quot;]*)&quot;</expression>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;id&gt;\2&lt;/id&gt;" dest="5+">
+ <expression>(imdb.com/)Title\?([0-9]+)</expression>
+ </RegExp>
+
+ <!--URL to Plot -->
+ <RegExp input="$$1" output="&lt;url function=&quot;Inhaltsangabe&quot;&gt;http://www.ofdb.de/plot/\1,\2,&lt;/url&gt;" dest="5+">
+ <expression>Inhalt:&lt;/b&gt;[^&lt;]*&lt;a href=&quot;plot/([0-9]+),([0-9]+),</expression>
+ </RegExp>
+
+ <!--URL to MPAA / Studio / Runtime-->
+ <RegExp input="$$1" output="&lt;url function=&quot;OFDbInfo&quot;&gt;http://www.ofdb.de/view.php?page=fassung&amp;amp;fid=\1&amp;amp;vid=\2&lt;/url&gt;" dest="5+">
+ <expression>&lt;a href=.view.php.page=fassung&amp;fid=([0-9]+)&amp;vid=([0-9]+).&gt;Kino:</expression>
+ </RegExp>
+
+ <!--URL to IMDB-->
+ <RegExp input="$$1" output="&lt;url function=&quot;IMDB-Details&quot;&gt;http://www.imdb.de/title/tt\2/&lt;/url&gt;" dest="5+">
+ <expression>(imdb.com/)Title\?([0-9]+)</expression>
+ </RegExp>
+
+ <!--URL to IMDBcredits-->
+ <RegExp input="$$1" output="&lt;url function=&quot;GetMovieCast&quot;&gt;http://www.imdb.de/title/tt\2/fullcredits#cast&lt;/url&gt;" dest="5+">
+ <expression>(imdb.com/)Title\?([0-9]+)</expression>
+ </RegExp>
+
+ <!--URL to Fanart-->
+ <RegExp conditional="fanart" input="$$1" output="&lt;url function=&quot;GetTMDBFanartByIMDBId&quot;&gt;http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=tt\2&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="5+">
+ <expression>(imdb.com/)Title\?([0-9]+)</expression>
+ </RegExp>
+
+ <!--URL to MoviePosterDB -->
+ <RegExp conditional="movieposterdb" input="$$1" output="&lt;url function=&quot;GetMoviePosterDBLink&quot;&gt;http://www.movieposterdb.com/browse/search?type=movies&amp;amp;query=\2&lt;/url&gt;" dest="5+">
+ <expression>(imdb.com/)Title\?([0-9]+)</expression>
+ </RegExp>
+
+ <!-- Ofdb Poster -->
+ <RegExp input="$$3" output="&lt;url function=&quot;GetOfdbThumb&quot; cache=&quot;$$2.html&quot;&gt;\1&lt;/url&gt;" dest="5+">
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!-- Cast -->
+ <RegExp input="$$2" output="&lt;url cache=&quot;$$2-credits.html&quot; function=&quot;GetMovieCast&quot;&gt;$$3&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+
+ <!--Plot-->
+ <Inhaltsangabe dest="5">
+ <RegExp input="$$7" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;&lt;plot&gt;\1&lt;/plot&gt;&lt;/details&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">Eine Inhaltsangabe von(.*)&lt;option value=&quot;All&quot;&gt;</expression>
+ </RegExp>
+ <RegExp input="$$9" output="\1" dest="7">
+ <expression noclean="1">&lt;br&gt;&lt;br&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$9" output=" \1" dest="7+">
+ <expression noclean="1" repeat="yes">&lt;br /&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <expression></expression>
+ </RegExp>
+ </Inhaltsangabe>
+
+ <!--Studio-->
+ <OFDbInfo dest="5">
+ <RegExp input="$$4" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="4+">
+ <expression>Verleih:&lt;/font&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;font[^&gt;]+&gt;&lt;b&gt;([^&lt;]+)&lt;/b&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="4+">
+ <expression>Laufzeit: ([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </OFDbInfo>
+
+ <!--IMDB-Details-->
+ <IMDB-Details dest="5">
+ <RegExp input="$$3" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;tagline&gt;\1&lt;/tagline&gt;" dest="3+">
+ <expression>Werbezeile:&lt;/h5&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <RegExp conditional="trailer" input="$$1" output="&lt;url function=&quot;GetTrailer&quot;&gt;http://akas.imdb.com/video/imdb/vi\1/player&lt;/url&gt;" dest="3+">
+ <expression>/vi([0-9]*)/&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">Drehbuchautor(.*)Premierendatum</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="3+">
+ <expression>&lt;a href=&quot;/name/nm[^&gt;]*&gt;([^&lt;]*)&lt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </IMDB-Details>
+
+ <!-- MovieCast -->
+ <GetMovieCast dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression noclean="1">&lt;table class=&quot;cast&quot;&gt;(.*?)&lt;/table&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;thumb&gt;\1_SX$INFO[imdbscale]_SY$INFO[imdbscale]_\2&lt;/thumb&gt;&lt;name&gt;\3&lt;/name&gt;&lt;role&gt;\4&lt;/role&gt;&lt;/actor&gt;" dest="7">
+ <expression repeat="yes" noclean="1,2" trim="3,4">&lt;img src=&quot;(?:([^&quot;]*\.)[^&quot;]*(\.jpg))?[^&gt;]*[^&quot;]*&quot;nm&quot;&gt;&lt;a href=&quot;[^&quot;]*[^&gt;]*&gt;([^&lt;]*)&lt;[^&quot;]*&quot;ddd&quot;&gt; ... [^&quot;]*&quot;char&quot;&gt;(.*?)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;actor&gt;&lt;thumb&gt;\1&lt;/thumb&gt;\2&lt;/actor&gt;" dest="2+">
+ <expression repeat="yes" noclean="1,2,3">&lt;actor&gt;&lt;thumb&gt;(?:(http.*?)|_SX[0-9]+_SY[0-9]+_)&lt;/thumb&gt;(.*?)&lt;/actor&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetMovieCast>
+
+ <!-- Trailer -->
+ <GetTrailer dest="5">
+ <RegExp conditional="trailer" input="$$2" output="&lt;details&gt;&lt;trailer urlencoded=&quot;yes&quot;&gt;\1&lt;/trailer&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="2">
+ <expression noclean="1">&quot;file&quot;[^&quot;]*&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="$$2/\1" dest="2">
+ <expression noclean="1">&quot;id&quot;[^&quot;]*&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetTrailer>
+
+ <!-- Ofdb Poster -->
+ <GetOfdbThumb dest="5">
+ <RegExp input="$$6" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="&lt;thumb&gt;http://img.ofdb.de/film/\1&lt;/thumb&gt;" dest="6+">
+ <expression>&lt;img src=&quot;http://img.ofdb.de/film/([^&quot;]+)&quot; [^&gt;]*&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetOfdbThumb>
+</scraper>
diff --git a/system/scrapers/video/ofdbxml.xml b/system/scrapers/video/ofdbxml.xml
new file mode 100644
index 0000000000..313b28a0b1
--- /dev/null
+++ b/system/scrapers/video/ofdbxml.xml
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<scraper framework="1.1" date="2009-07-28" name="OFDb (XML)" content="movies" thumb="ofdb.png" language="de">
+ <include>common/tmdb.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Fanart&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://xml.n4rf.net/ofdbgw/movie/\2&lt;/url&gt;" dest="3">
+ <expression clear="yes" noclean="1">(http://www.ofdb.de/film/)([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetByIMDBId&quot;&gt;http://xml.n4rf.net/ofdbgw/imdb2ofdb/tt\2&lt;/url&gt;" dest="3+">
+ <expression>(imdb.com/)Title\?([0-9]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetByIMDBId&quot;&gt;http://xml.n4rf.net/ofdbgw/imdb2ofdb/tt\2&lt;/url&gt;" dest="3+">
+ <expression>(imdb.com/title/tt)([0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+
+ <GetByIMDBId dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://xml.n4rf.net/ofdbgw/movie/\1&lt;/url&gt;" dest="3+">
+ <expression repeat="yes">&lt;ofdbid&gt;([^&lt;]+)</expression>
+ </RegExp>
+ </GetByIMDBId>
+
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="http://xml.n4rf.net/ofdbgw/search/\1" dest="3">
+ <expression noclean="1"/>
+ </RegExp>
+ </CreateSearchUrl>
+
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;year&gt;\3&lt;/year&gt;&lt;url&gt;http://xml.n4rf.net/ofdbgw/movie/\1&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes">&lt;id&gt;(.*?)&lt;/id&gt;\n&lt;titel&gt;([^&lt;]+)&lt;/titel&gt;.*?&lt;jahr&gt;(.*?)&lt;/jahr&gt;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetSearchResults>
+
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$6" output="\1" dest="5+">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="6">
+ <expression trim="1">&lt;titel&gt;([^&lt;]+)&lt;/titel&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;title&gt;\2 \1&lt;/title&gt;" dest="6">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression trim="1">&lt;titel&gt;([^&lt;]+)&lt;/titel&gt;</expression>
+ </RegExp>
+ <expression>(.*), (Die|Der|Das|The)</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;originaltitle&gt;\1&lt;/originaltitle&gt;" dest="5+">
+ <expression noclean="1">&lt;alternativ&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression noclean="1">&lt;jahr&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;regie&gt;(.*?)&lt;/regie&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">&lt;name&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;genre&gt;(.*?)&lt;/genre&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">&lt;titel&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;drehbuch&gt;(.*?)&lt;/drehbuch&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">&lt;name&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$9" output="&lt;actor&gt;&lt;name&gt;\2&lt;/name&gt;&lt;role&gt;\3&lt;/role&gt;&lt;/actor&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="9">
+ <expression noclean="1">&lt;besetzung&gt;(.*?)&lt;/besetzung&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">&lt;id&gt;([^&lt;]+)&lt;/id&gt;\n&lt;name&gt;([^&lt;]+)&lt;/name&gt;\n&lt;rolle&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;" dest="5+">
+ <expression>&lt;kurzbeschreibung&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>&lt;beschreibung&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="5+">
+ <expression>&lt;note&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;votes&gt;\1&lt;/votes&gt;" dest="5+">
+ <expression>&lt;stimmen&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetOFDBData&quot;&gt;http://xml.n4rf.net/ofdbgw/fassung/\1&lt;/url&gt;" dest="5+">
+ <expression>&lt;fassungen&gt;.*?&lt;id&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="5+">
+ <expression>&lt;bild&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp conditional="fanart" input="$$1" output="&lt;url function=&quot;GetTMDBFanartByIMDBId&quot;&gt;http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=tt\1&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="5+">
+ <expression>&lt;imdbid&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetDetails>
+
+ <GetOFDBData dest="5">
+ <RegExp input="$$6" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;\1&lt;/details&gt;" dest="5+">
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="6+">
+ <expression trim="1">&lt;label&gt;([^&lt;|^(]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;" dest="6+">
+ <expression trim="1">&lt;freigabe&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="6+">
+ <expression trim="1">&lt;laufzeit&gt;([^&lt;]+)</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetOFDBData>
+</scraper>
diff --git a/system/scrapers/video/ptgate.jpg b/system/scrapers/video/ptgate.jpg
new file mode 100644
index 0000000000..b240e4327f
--- /dev/null
+++ b/system/scrapers/video/ptgate.jpg
Binary files differ
diff --git a/system/scrapers/video/ptgate.xml b/system/scrapers/video/ptgate.xml
new file mode 100644
index 0000000000..629849fd8a
--- /dev/null
+++ b/system/scrapers/video/ptgate.xml
@@ -0,0 +1,280 @@
+п»ї<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.1" date="2009-08-10" name="PTGate and IMDb" content="movies" thumb="ptgate.jpg" language="pt">
+ <include>common/tmdb.xml</include>
+ <include>common/movieposterdb.xml</include>
+ <include>common/impa.xml</include>
+ <include>common/imdb.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Utilizar apenas o Cinema PTGate&quot; type=&quot;bool&quot; id=&quot;ptgateonly&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting type=&quot;sep&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Incluir detalhes e fotos dos Actores&quot; type=&quot;bool&quot; id=&quot;fullcredits&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Incluir detalhes do IMPAwards&quot; type=&quot;bool&quot; id=&quot;impawards&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Incluir detalhes do MoviePosterDB&quot; type=&quot;bool&quot; id=&quot;movieposterdb&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Incluir trailer&quot; type=&quot;bool&quot; id=&quot;trailer&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Incluir Fanart&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Tamanhos do Poster e das Fotos dos Actores&quot; type=&quot;labelenum&quot; values=&quot;192|256|384|512|1024&quot; id=&quot;imdbscale&quot; default=&quot;512&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting type=&quot;sep&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Url para acesso ao IMDb&quot; type=&quot;text&quot; id=&quot;url&quot; default=&quot;akas.imdb.com&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="\1" dest="3">
+ <expression clear="yes" noclean="1">(http://www.cinema.ptgate.pt/filmes/[0-9]*)</expression>
+ </RegExp>
+ </NfoUrl>
+
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.cinema.ptgate.pt/pesquisa/?q=\1&lt;/url&gt;" dest="3">
+ <expression noclean="1">([^\(]+)</expression>
+ </RegExp>
+ </CreateSearchUrl>
+
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp dest="5+" input="$$1" output="&lt;entity&gt;&lt;title&gt;\2 - \4 (\3)&lt;/title&gt;&lt;url&gt;http://www.cinema.ptgate.pt/filmes/\1&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;">
+ <expression repeat="yes" trim="2,3">&lt;a href=&quot;/filmes/([0-9]*)&quot;&gt;(.*?)&lt;/a&gt; &lt;small&gt;([^\(]*)\(([0-9]*)\)</expression>
+ </RegExp>
+ <RegExp dest="5" input="$$1" output="&lt;entity&gt;&lt;title&gt;\2 - \3 (\4)&lt;/title&gt;&lt;url&gt;http://www.cinema.ptgate.pt/filmes/\1&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;">
+ <expression trim="2,4">&lt;a href=&quot;/filmes/([0-9]*)&quot; class=&quot;upper&quot;&gt;([^&lt;]*)&lt;/a&gt; &lt;small&gt;\(([0-9]*)\)&lt;br /&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+
+ <GetDetails clearbuffers="no" dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <!-- Id -->
+ <RegExp dest="5" input="$$2" output="&lt;id&gt;\1&lt;/id&gt;">
+ <expression></expression>
+ </RegExp>
+
+ <!-- Title -->
+ <RegExp dest="5+" input="$$1" output="&lt;title&gt;\1&lt;/title&gt;">
+ <expression>&lt;h2&gt;([^&lt;]*)&lt;/h2&gt;</expression>
+ </RegExp>
+
+ <!-- Plot -->
+ <RegExp dest="5+" input="$$1" output=";&lt;plot&gt;\1&lt;/plot&gt;">
+ <expression>&lt;b&gt;sinopse[^\n]*\s+([^\n]*)</expression>
+ </RegExp>
+
+ <!-- Outline -->
+ <RegExp dest="5+" input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;">
+ <expression>&lt;b&gt;sinopse[^\n]*\s+(.*?[^A-Z]\.)</expression>
+ </RegExp>
+
+ <!-- Genre -->
+ <RegExp dest="5+" input="$$9" output="&lt;genre&gt;\1&lt;/genre&gt;">
+ <RegExp dest="9" input="$$1" output="\1,">
+ <expression>&lt;b&gt;g.nero&lt;/b&gt;: ([^&lt;]*)</expression>
+ </RegExp>
+ <expression repeat="yes" trim="1">([^,]+),</expression>
+ </RegExp>
+
+ <!-- Year -->
+ <RegExp dest="11" input="$$1" output="&lt;year&gt;\1&lt;/year&gt;">
+ <expression>&lt;b&gt;ano&lt;/b&gt;: ([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp dest="5+" input="$$11" output="\1">
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!-- Actor -->
+ <RegExp dest="8" input="$$9" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;">
+ <RegExp input="$$1" output="\1," dest="9">
+ <expression>&lt;b&gt;int.rpretes&lt;/b&gt;&lt;br /&gt;\s*(.*?)&lt;br /&gt;</expression>
+ </RegExp>
+ <expression clear="yes" repeat="yes" trim="1">([^,]*),</expression>
+ </RegExp>
+ <RegExp dest="4" input="$$8" output="&lt;actors&gt;\1&lt;/actors&gt;">
+ <expression noclean="1"></expression>
+ </RegExp>
+ <RegExp dest="5+" input="$$8" conditional="ptgateonly" output="\1">
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!-- Director -->
+ <RegExp dest="8" input="$$9" output="&lt;director&gt;\1&lt;/director&gt;">
+ <RegExp input="$$1" output="\1," dest="9">
+ <expression>&lt;b&gt;realiza..o&lt;/b&gt;&lt;br /&gt;\s*(.*?)&lt;br /&gt;</expression>
+ </RegExp>
+ <expression repeat="yes" trim="1">([^,]+),</expression>
+ </RegExp>
+ <RegExp dest="4+" input="$$8" output="&lt;directors&gt;\1&lt;/directors&gt;">
+ <expression noclean="1"></expression>
+ </RegExp>
+ <RegExp dest="5+" input="$$8" conditional="ptgateonly" output="\1">
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!-- Add PTGate image as last Thumb -->
+ <RegExp dest="12" input="$$2" output="&lt;thumb&gt;http://www.cinema.ptgate.pt/Movies/\1.jpg&lt;/thumb&gt;">
+ <expression></expression>
+ </RegExp>
+ <RegExp dest="5+" input="$$12" conditional="ptgateonly" output="\1">
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!-- Add PT Distributor -->
+ <RegExp dest="13" input="$$1" output="&lt;studio&gt;Dist: \1&lt;/studio&gt;">
+ <expression>&lt;b&gt;distribuidora&lt;/b&gt;: ([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp dest="5+" input="$$13" conditional="ptgateonly" output="\1">
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!-- IMDB Details -->
+ <RegExp dest="5+" input="$$10" conditional="!ptgateonly" output="\1">
+ <!-- Use Google as last resort -->
+ <RegExp dest="10" input="$$8" output="&lt;url function=&quot;GetIMDBfromGoogle&quot;&gt;http://www.google.com/search?q=site:imdb.com\1&lt;/url&gt;">
+ <!-- search google for the original title -->
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression trim="1">\&amp;#8250; ([^&lt;]+)&lt;br /&gt;</expression>
+ </RegExp>
+ <!-- add year to search string -->
+ <RegExp input="$$11" output="+\1" dest="8">
+ <expression></expression>
+ </RegExp>
+ <!-- remove spaces and , -->
+ <RegExp input="$$7" output="+\1" dest="8+">
+ <expression repeat="yes">([^ ,]+)</expression>
+ </RegExp>
+ <expression></expression>
+ </RegExp>
+
+ <!-- use IMDB link on PTGATE, when available -->
+ <RegExp dest="10" input="$$9" output="&lt;url function=&quot;GetIMDBDetails&quot;&gt;http://$INFO[url]/title/\1/&lt;/url&gt;">
+ <RegExp dest="9" input="$$1" output="\1">
+ <expression clear="yes">\.imdb\.com/title/(tt[0-9]*)</expression>
+ </RegExp>
+ <expression>(.+)</expression>
+ </RegExp>
+
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+
+
+ <GetIMDBfromGoogle clearbuffers="no" dest="3">
+ <RegExp input="$$5" dest="3" output="&lt;details&gt;\1&lt;/details&gt;">
+ <RegExp input="$$1" dest="5" output="&lt;url function=&quot;GetIMDBDetails&quot;&gt;http://$INFO[url]/title/\1/&lt;/url&gt;">
+ <expression>\.imdb\.com/title/(tt[0-9]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetIMDBfromGoogle>
+ <GetIMDBDetails clearbuffers="no" dest="3">
+ <RegExp input="$$5" dest="3" output="&lt;details&gt;\1&lt;/details&gt;">
+ <!-- IMDB Id -->
+ <RegExp input="$$1" dest="2" output="\1">
+ <expression>id=(tt[t0-9]*)</expression>
+ </RegExp>
+
+ <!-- Studio -->
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="5">
+ <expression clear="yes" repeat="yes">&quot;/company/[^/]*/&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$13" output="\1" dest="5+">
+ <expression noclean="1"></expression>
+ </RegExp>
+
+ <!-- Certificates -->
+ <RegExp input="$$1" output="&lt;certification&gt;\1 \3&lt;/certification&gt;" dest="5+">
+ <expression repeat="yes">&lt;a href=&quot;/List\?certificates=[^&quot;]*&quot;&gt;([^&lt;]*)&lt;/a&gt;[^&lt;]*(&lt;i&gt;([^&lt;]*)&lt;/i&gt;)?</expression>
+ </RegExp>
+
+ <!-- Runtime -->
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression trim="1">&lt;h5&gt;Runtime:&lt;/h5&gt;[^0-9]*([^&lt;|]*)</expression>
+ </RegExp>
+
+ <!-- Rating -->
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;&lt;votes&gt;\2&lt;/votes&gt;" dest="5+">
+ <expression>&lt;b&gt;([0-9.]+)/10&lt;/b&gt;[^&lt;]*&lt;a href=&quot;ratings&quot; class=&quot;tn15more&quot;&gt;([0-9,]+) votes&lt;/a&gt;</expression>
+ </RegExp>
+
+ <!-- Actor -->
+ <RegExp conditional="!fullcredits" input="$$2" output="&lt;url cache=&quot;$$2-credits.html&quot; function=&quot;GetIMDBCast&quot;&gt;$$3&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+
+ <!-- Director -->
+ <RegExp conditional="!fullcredits" input="$$2" output="&lt;url cache=&quot;$$2-credits.html&quot; function=&quot;GetMovieDirectors&quot;&gt;$$3&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+
+ <!-- Credits -->
+ <RegExp conditional="!fullcredits" input="$$2" output="&lt;url cache=&quot;$$2-credits.html&quot; function=&quot;GetIMDBWriters&quot;&gt;$$3&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+
+ <!-- Actor, full -->
+ <RegExp conditional="fullcredits" input="$$2" output="&lt;url cache=&quot;$$2-fullcredits.html&quot; function=&quot;GetIMDBCast&quot;&gt;$$3fullcredits&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+
+ <!-- Director, full -->
+ <RegExp conditional="fullcredits" input="$$2" output="&lt;url cache=&quot;$$2-fullcredits.html&quot; function=&quot;GetIMDBDirectors&quot;&gt;$$3fullcredits&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+
+ <!-- Credits, full -->
+ <RegExp conditional="fullcredits" input="$$2" output="&lt;url cache=&quot;$$2-fullcredits.html&quot; function=&quot;GetIMDBWriters&quot;&gt;$$3fullcredits&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+
+ <!-- Thumb, IMPAwards -->
+ <RegExp conditional="impawards" input="$$2" output="&lt;url cache=&quot;$$2-posters.html&quot; function=&quot;GetIMPALink&quot;&gt;$$3posters&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+
+ <!-- Poster, MoviePosterDB -->
+ <RegExp conditional="movieposterdb" input="$$1" output="&lt;url function=&quot;GetMoviePosterDBLink&quot;&gt;http://www.movieposterdb.com/browse/search?type=movies&amp;amp;query=\1&lt;/url&gt;" dest="5+">
+ <expression>/title/tt([t0-9]*)/faq</expression>
+ </RegExp>
+
+ <!-- Trailer -->
+ <RegExp conditional="trailer" input="$$1" output="&lt;url function=&quot;GetIMDBTrailer&quot;&gt;http://$INFO[url]/video/imdb/vi\1/player&lt;/url&gt;" dest="5+">
+ <expression>/vi([0-9]*)/&quot;</expression>
+ </RegExp>
+
+ <!-- Thumb, IMDB -->
+ <RegExp input="$$2" output="&lt;url cache=&quot;$$2-posters.html&quot; function=&quot;GetIMDBPoster&quot;&gt;$$3posters&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+
+ <!-- Fanart -->
+ <RegExp conditional="fanart" input="$$2" output="&lt;url function=&quot;GetTMDBFanartByIMDBId&quot;&gt;http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=$$2&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetIMDBDetails>
+</scraper>
diff --git a/system/scrapers/video/speedallocinev2.xml b/system/scrapers/video/speedallocinev2.xml
new file mode 100644
index 0000000000..912c3f5fdd
--- /dev/null
+++ b/system/scrapers/video/speedallocinev2.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<scraper framework="1.0" date="2009-05-30" name="speedallocinev2.fr" content="movies" thumb="allocine.jpg" language="fr">
+
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="http://passion-xbmc.org/scraper/index.php?search=\1" dest="3">
+ <expression></expression>
+ </RegExp>
+ </CreateSearchUrl>
+
+ <GetSearchResults dest="2">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="2">
+ <RegExp input="$$1" output="\1" dest="5">
+ <expression trim="1" noclean="1">(.*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+
+ <GetDetails clearbuffers="no" dest="3">
+ <RegExp input="$$5" output="\1" dest="3">
+ <RegExp input="$$1" output="\1" dest="5">
+ <expression trim="1" noclean="1">(.*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+
+</scraper>
diff --git a/system/scrapers/video/sratim.gif b/system/scrapers/video/sratim.gif
new file mode 100644
index 0000000000..d3baf9fcc7
--- /dev/null
+++ b/system/scrapers/video/sratim.gif
Binary files differ
diff --git a/system/scrapers/video/sratim.xml b/system/scrapers/video/sratim.xml
new file mode 100644
index 0000000000..5eea36a530
--- /dev/null
+++ b/system/scrapers/video/sratim.xml
@@ -0,0 +1,115 @@
+п»ї<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.0" date="2009-05-22" name="Sratim" content="movies" thumb="sratim.gif" language="il">
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Full Cast Credits&quot; type=&quot;bool&quot; id=&quot;fullcredits&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Trailer&quot; type=&quot;bool&quot; id=&quot;trailer&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Fanart&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Get Rank From IMDB&quot; type=&quot;bool&quot; id=&quot;imdbrank&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.sratim.co.il/movies/search.aspx?Keyword=\1&lt;/url&gt;" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url&gt;http://www.sratim.co.il/\1&lt;/url&gt;&lt;/entity&gt;" dest="5">
+ <expression clear="yes" noclean="1" repeat="yes">&lt;table class="MovieViews".*?&gt;.*?&lt;a href="(.[^"]*)"&gt;(.*?)&lt;div&gt;.*?&lt;/table&gt;</expression>
+ </RegExp>
+ <expression clear="yes" noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails clearbuffers="no" dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5+">
+ <expression trim="1" noclean="1">&lt;div.*?class="Box_Header"&gt;&lt;table.*?&gt;&lt;tr&gt;&lt;td.*?&gt;(.*?)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression trim="1">&lt;u&gt;ЧЄЧ§Ч¦Ч™ЧЁ:&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;(.*?)&lt;/div&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression trim="1" repeat="yes">&lt;a href="/movies/search.aspx\?g=.*?"&gt;(.*?)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression repeat="no" noclean="1">&lt;b&gt;Ч©Ч—Ч§Ч Ч™Чќ:&lt;/b&gt;(.*?)&lt;br /&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="5+">
+ <expression trim="1" repeat="yes">&lt;a href="/movies/companies/view.aspx\?id=.*?"&gt;(.*?)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;" dest="5+">
+ <expression trim="1" repeat="yes">&lt;a href="/movies/actors/view.aspx\?id=.*?"&gt;(.*?)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp conditional="!fullcredits" input="$$7" output="&lt;url function=&quot;GetActorDetails&quot;&gt;http://www.sratim.co.il/movies/actors/view.aspx?id=\1&lt;/url&gt;" dest="5+"><expression repeat="yes">&lt;a href="/movies/actors/view.aspx\?id=(.*?)"&gt;</expression></RegExp><RegExp input="$$1" output="\1" dest="7">
+ <expression repeat="no" noclean="1">&lt;b&gt;Ч‘ЧћЧђЧ™:&lt;/b&gt;(.*?)&lt;br /&gt;</expression>
+ </RegExp>
+ <RegExp input="$$7" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <expression trim="1" repeat="yes">&lt;a href="/movies/actors/view.aspx\?id=.*?"&gt;(.*?)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression trim="1">&lt;span id="ctl00_ctl00_Body_Body_Box_ProductionYear"&gt;(.*?)&lt;/span&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="5+" conditional="!imdbrank">
+ <expression trim="1" repeat="no">&lt;img alt="(.*?)/10" src="/Images/Star_Big_.*?.gif" /&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;votes&gt;\1&lt;/votes&gt;" dest="5+" conditional="!imdbrank">
+ <expression trim="1" repeat="no">&lt;span.*?&gt;([0-9]+?) ЧћЧ“ЧЁЧ’Ч™Чќ&lt;/span&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression trim="1" repeat="no">&lt;b&gt;ЧђЧ•ЧЁЧљ:&lt;/b&gt; ([0-9]+?) Ч“Ч§Ч•ЧЄ.</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;http://www.sratim.co.il\1&lt;/thumb&gt;" dest="5+">
+ <expression trim="1" repeat="no">&lt;img src="(/movies/images/.*?)" id="ctl00_ctl00_Body_Body_Box_MainPicture"</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetIMDBDetails&quot;&gt;http://www.imdb.com/title/\1/&lt;/url&gt;" dest="5+">
+ <expression trim="1" repeat="no">http://www\.imdb\.com/title/(tt\d+?)'</expression>
+ </RegExp>
+ <RegExp conditional="fanart" input="$$1" output="&lt;url function=&quot;GetTMDBFanartByIMDBId&quot;&gt;http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=\1&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="5+">
+ <expression trim="1" repeat="no">http://www\.imdb\.com/title/(tt\d+?)'</expression>
+ </RegExp>
+ <RegExp conditional="imdbrank" input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="5+">
+ <expression trim="1" repeat="no">&lt;img alt="([0-9]+\.[0-9]*)/10" src="/Images/Star_IMDB</expression>
+ </RegExp>
+ <RegExp conditional="imdbrank" input="$$1" output="&lt;votes&gt;\1&lt;/votes&gt;" dest="5+">
+ <expression trim="1" repeat="no">Star_IMDB.*?&lt;span.*?&gt;([0-9]+?) ЧћЧ“ЧЁЧ’Ч™Чќ&lt;/span&gt;</expression>
+ </RegExp>
+ </RegExp>
+ </GetDetails>
+ <GetActorDetails clearbuffers="no" dest="5"><RegExp input="$$2" output="&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <expression noclean="1"></expression>
+ <RegExp input="$$1" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;thumb&gt;http://www.sratim.co.il\2&lt;/thumb&gt;&lt;/actor&gt;" dest="2+">
+ <expression clear="yes" repeat="no">&lt;div class="Box_Header"&gt;.*?&lt;span.*?&gt;(.*?)&lt;/span&gt;.*?&lt;div class="Box_Body"&gt;.*?&lt;img.*?src="(/movies/Actors/Images/.*?)" /&gt;</expression>
+ </RegExp>
+ </RegExp>
+ </GetActorDetails>
+ <GetIMDBDetails dest="5">
+ <RegExp input="$$3" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;\1&lt;/details&gt;" dest="5">
+ <RegExp conditional="trailer" input="$$1" output="&lt;url function=&quot;GetTrailer&quot;&gt;http://akas.imdb.com/video/imdb/vi\1/player&lt;/url&gt;" dest="3+">
+ <expression>/vi([0-9]*)/&quot;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetIMDBDetails>
+ <GetTrailer clearbuffers="no" dest="5">
+ <RegExp input="$$2" output="&lt;details&gt;&lt;trailer urlencoded=&quot;yes&quot;&gt;\1&lt;/trailer&gt;&lt;/details&gt;" dest="5">
+ <RegExp input="$$1" output="\1" dest="2">
+ <expression noclean="1">&quot;file&quot;[^&quot;]*&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="$$2/\1" dest="2">
+ <expression noclean="1">&quot;id&quot;[^&quot;]*&quot;([^&quot;]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetTrailer>
+</scraper>
diff --git a/system/scrapers/video/tmdb.png b/system/scrapers/video/tmdb.png
new file mode 100644
index 0000000000..377f6af8a5
--- /dev/null
+++ b/system/scrapers/video/tmdb.png
Binary files differ
diff --git a/system/scrapers/video/tmdb.xml b/system/scrapers/video/tmdb.xml
new file mode 100644
index 0000000000..92c688cf82
--- /dev/null
+++ b/system/scrapers/video/tmdb.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.1" date="2009-07-28" name="themoviedb.org" content="movies" thumb="tmdb.png" language="en">
+ <include>common/tmdb.xml</include>
+ <include>common/dtrailer.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Fanart&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Trailers from Dtrailer.com&quot; type=&quot;bool&quot; id=&quot;trailer&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://api.themoviedb.org/2.0/Movie.search?title=\1&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="3">
+ <RegExp input="$$2" output="%20(\1)" dest="4">
+ <expression clear="yes">(.+)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://api.themoviedb.org/2.0/Movie.getInfo?id=\2&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;&lt;id&gt;\2&lt;/id&gt;" dest="3">
+ <expression clear="yes" noclean="1">(themoviedb.org/movie/)([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetTMDBId&quot;&gt;http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=tt\2&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="3+">
+ <expression>(imdb.com/title/tt)([0-9]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url function=&quot;GetTMDBId&quot;&gt;http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=tt\2&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="3+">
+ <expression>(imdb.com/)Title\?([0-9]+)</expression>
+ </RegExp>
+ </NfoUrl>
+ <GetTMDBId dest="3">
+ <RegExp input="$$1" output="&lt;url cache=&quot;tmdb-\1.xml&quot;&gt;http://api.themoviedb.org/2.0/Movie.getInfo?id=\1&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;" dest="3+">
+ <expression>&lt;id&gt;([0-9]*)&lt;/id&gt;</expression>
+ </RegExp>
+ </GetTMDBId>
+ <GetSearchResults dest="8">
+ <RegExp input="$$3" output="&lt;results&gt;\1&lt;/result&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\1&lt;/title&gt;&lt;id&gt;\2&lt;/id&gt;&lt;year&gt;\3&lt;/year&gt;&lt;url cache=&quot;tmdb-\2.xml&quot; &gt;http://api.themoviedb.org/2.0/Movie.getInfo?id=\2&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;&lt;/entity&gt;" dest="3">
+ <expression repeat="yes">&lt;movie&gt;.*?&lt;title&gt;([^&lt;]*)&lt;/title&gt;.*?&lt;id&gt;([^&lt;]*)&lt;/id&gt;.*?&lt;release&gt;([0-9]+).*?&lt;/movie&gt;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression>&lt;title&gt;([^&lt;]*)&lt;/title&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>&lt;release&gt;([0-9]+)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression>&lt;runtime&gt;([^&lt;]*)&lt;/runtime&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="5+">
+ <expression>&lt;rating&gt;([^&lt;]*)&lt;/rating&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes">&lt;category&gt;.*?&lt;name&gt;([^&lt;]*)&lt;/name&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>&lt;short_overview&gt;([^&lt;]*)&lt;/short_overview&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;outline&gt;\1&lt;/outline&gt;" dest="5+">
+ <expression>&lt;short_overview&gt;([^&lt;]*)&lt;/short_overview&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <expression repeat="yes">&lt;person job=&quot;director&quot;.*?&lt;name&gt;([^&lt;]*)&lt;/name&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="5+">
+ <expression repeat="yes">&lt;person job=&quot;author&quot;.*?&lt;name&gt;([^&lt;]*)&lt;/name&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\2&lt;/role&gt;&lt;/actor&gt;" dest="5+">
+ <expression repeat="yes">&lt;person job=&quot;actor&quot;.*?&lt;name&gt;([^&lt;]*)&lt;/name&gt;.*?&lt;role&gt;([^&lt;]*)&lt;/role&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url cache=&quot;tmdb-$$2.xml&quot; function=&quot;GetTMDBThumbs&quot;&gt;$$3&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+
+ <RegExp conditional="fanart" input="$$1" output="&lt;url cache=&quot;tmdb-$$2.xml&quot; function=&quot;GetTMDBFanart&quot;&gt;$$3&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp conditional="trailer" input="$$6" output="&lt;url function=&quot;GetDTrailerLink&quot;&gt;http://en.dtrailer.com/movies/search/\1&lt;/url&gt;" dest="5+">
+ <RegExp input="$$4" output="\1-" dest="6">
+ <RegExp input="$$1" output="\1" dest="4">
+ <expression>&lt;title&gt;([^&lt;]*)&lt;/title&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">([a-zA-Z0-9]+)</expression>
+ </RegExp>
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetDetails>
+</scraper>
diff --git a/system/scrapers/video/tvcom.png b/system/scrapers/video/tvcom.png
new file mode 100644
index 0000000000..1901b1e93f
--- /dev/null
+++ b/system/scrapers/video/tvcom.png
Binary files differ
diff --git a/system/scrapers/video/tvcom.xml b/system/scrapers/video/tvcom.xml
new file mode 100644
index 0000000000..c4f391ebd3
--- /dev/null
+++ b/system/scrapers/video/tvcom.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.0" date="2009-05-22" name="TV.com" content="tvshows" thumb="tvcom.png" language="en">
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.tv.com/search.php?type=Search&amp;amp;stype=ajax_search&amp;amp;qs=\1&amp;amp;search_type=program&amp;amp;pg_results=0&amp;amp;sort=&lt;/url&gt;" dest="3">
+ <expression></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="3">
+ <RegExp input="$$4" output="&lt;results&gt;\1&lt;/results&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url&gt;http://www.tv.com/show/\1/summary.html&lt;/url&gt;&lt;url&gt;http://www.tv.com/show/\1/cast.html&lt;/url&gt;&lt;url&gt;http://www.tv.com/show/\1/episode_listings.html?season=All&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;" dest="4">
+ <expression repeat="yes" noclean="1">&lt;a href=&quot;http://www\.tv\.com/[^/]*/show/([0-9]+)/summary\.html[^&quot;]*&quot;[^&gt;]*&gt;([^&lt;]+)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails dest="7">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="7">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression noclean="1">&lt;title&gt;([^&lt;]*) on TV\.com</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes" noclean="1">;genre;[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+<!-- <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>id=&quot;summary_fold&quot; class=&quot;mt-10&quot;&gt;\W*(.*?) *?&lt;/div&gt;</expression>
+ </RegExp> -->
+
+ <RegExp input="$$8" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression>&lt;span class=&quot;long&quot;&gt;(.*)&lt;/span&gt;[^&lt;]*&lt;span class=&quot;short&quot;&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="\1" dest="8">
+ <expression repeat="yes"></expression>
+ </RegExp>
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="5+">
+ <expression>&lt;span&gt;Show Score&lt;/span&gt;[^0-9]*([0-9\.]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;votes&gt;\1&lt;/votes&gt;" dest="5+">
+ <expression>&lt;span&gt;([0-9,]*)&lt;/span&gt;[^&lt;]*Votes</expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\2&lt;/role&gt;&lt;/actor&gt;" dest="5+">
+ <expression repeat="yes">&gt;([^&lt;]*)&lt;/a&gt;&lt;/h3&gt; &lt;a class=&quot;photos_link&quot; href=&quot;http://www\.tv\.com/[^/]*/person/[0-9]*/photos\.html\?tag=cast;stars;photos;[0-9]*&quot;&gt;\(photos\)&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;role&quot;&gt;Role: ([^&lt;]*)&lt;/div&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="5+">
+ <expression>(http://image\.com\.com/tv/images/content_headers/program_new/[0-9]*\.jpg)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;status&gt;\1&lt;/status&gt;" dest="5+">
+ <expression trim="1">&lt;span class=&quot;program_status_name&quot;&gt;([^&lt;]*)&lt;/span&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;premiered&gt;\1&lt;/premiered&gt;" dest="5+">
+ <expression trim="1">&lt;span class=&quot;start_date&quot;&gt;([^&lt;]*)&lt;/span&gt;</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;episodeguide&gt;\1&lt;/episodeguide&gt;" dest="5+">
+ <RegExp input="$$3" output="&lt;url&gt;http://www.tv.com/show/$$4/episode_listings.html?season=\1&lt;/url&gt;" dest="8">
+ <expression repeat="yes">/show/[0-9]+/episode_listings\.html\?season=([0-9]+)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+
+ <GetEpisodeList dest="3">
+ <RegExp input="$$5" output="&lt;episodeguide&gt;\1&lt;/episodeguide&gt;" dest="3">
+ <RegExp input="$$1" output="\1" dest="6">
+ <expression>&amp;nbsp;[^&lt;]*&lt;strong&gt;([0-9]+)&lt;/strong&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;episode&gt;&lt;title&gt;\3&lt;/title&gt;&lt;id&gt;\2&lt;/id&gt;&lt;url &gt;http://www.tv.com/episode/\2/summary.html&lt;/url&gt;&lt;epnum&gt;\1&lt;/epnum&gt;&lt;season&gt;$$6&lt;/season&gt;&lt;/episode&gt;" dest="5">
+ <expression repeat="yes">&lt;div&gt;([0-9]*)&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;ep_title&quot;&gt;&lt;div&gt;&lt;a href=&quot;http://www\.tv\.com/[^/]*/[^/]*/episode/([0-9]*)/summary\.html[^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetEpisodeList>
+
+ <GetEpisodeDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression>&lt;div class=&quot;content_title&quot;&gt;[^&lt;]*&lt;h1&gt;[^:]*:([^&lt;]*)&lt;/h1&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>&lt;p class=&quot;deck&quot;&gt;([^=]*)&lt;a </expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="5+">
+ <expression>Episode score[^&lt;]*&lt;span&gt;([0-9\.]*)&lt;/span&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;aired&gt;\1&lt;/aired&gt;" dest="5+">
+ <expression>&lt;span&gt;First Aired:&lt;/span&gt;([^&lt;]*)&lt;/li&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\2&lt;/role&gt;&lt;/actor&gt;" dest="5+">
+ <expression repeat="yes">&quot;&gt;([^&lt;]*)&lt;/a&gt; \(([^&lt;]*)\)[^&lt;]*&lt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <expression>Director:&lt;/dt&gt;&lt;dd&gt;&lt;a [^&gt;]*&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="5+">
+ <expression>writer;0&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="5+">
+ <expression>(http://image\.com\.com/tv/images/content_headers/episode_new/[0-9]*\.jpg)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;code&gt;\1&lt;/code&gt;" dest="5+">
+ <expression>&lt;span&gt;Prod Code:&lt;/span&gt;([^&lt;]*)&lt;/li&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetEpisodeDetails>
+
+</scraper>
diff --git a/system/scrapers/video/tvdb.png b/system/scrapers/video/tvdb.png
new file mode 100644
index 0000000000..36c48cdbb6
--- /dev/null
+++ b/system/scrapers/video/tvdb.png
Binary files differ
diff --git a/system/scrapers/video/tvdb.xml b/system/scrapers/video/tvdb.xml
new file mode 100644
index 0000000000..559902a12b
--- /dev/null
+++ b/system/scrapers/video/tvdb.xml
@@ -0,0 +1,304 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- should be self-explanatory -->
+<scraper framework="1.1" date="2009-07-28" name="TheTVDB.com" content="tvshows" thumb="tvdb.png" language="multi">
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;url function=&quot;GetLanguages&quot;&gt;http://www.thetvdb.com/api/1D62F2F90030C444/languages.xml&lt;/url&gt;" dest="5">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Use DVD Order&quot; type=&quot;bool&quot; id=&quot;dvdorder&quot; default=&quot;false&quot; enable=&quot;!eq(1,true)&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <!-- Absolute ordering is great for Animes it actually trick XBMC by telling it that the serie has only one season and uses the 'absolute_number' as episodes numbers -->
+ <RegExp input="$$1" output="&lt;setting label=&quot;Use Absolute Ordering (Single Season)&quot; type=&quot;bool&quot; id=&quot;absolutenumber&quot; default=&quot;false&quot; enable=&quot;!eq(-1,true)&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting type=&quot;sep&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Enable Fanart&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Prefer Posters&quot; type=&quot;bool&quot; id=&quot;posters&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting type=&quot;sep&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Language Override for Banners&quot; type=&quot;bool&quot; id=&quot;override&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+
+ <NfoUrl dest="3">
+ <RegExp input="$$1" output="&lt;url cache=&quot;\1.xml&quot;&gt;http://www.thetvdb.com/api/1D62F2F90030C444/series/\1/all/$INFO[language].zip&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;" dest="3">
+ <expression>http://(?:www\.)?thetvdb.com/(?:index\.php)?\?tab=series&amp;id=([0-9]+)</expression>
+ </RegExp>
+ </NfoUrl>
+ <EpisodeGuideUrl dest="3">
+ <RegExp input="$$1" output="\1" dest="3">
+ <expression>(.*?http://www.thetvdb.com.*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="\1" dest="3">
+ <expression>(.*?http://thetvdb.com.*)</expression>
+ </RegExp>
+ </EpisodeGuideUrl>
+
+ <!-- input: $1=query string -->
+ <!-- returns: the url we should use to do the search -->
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="http://www.thetvdb.com/api/GetSeries.php?seriesname=\1$$4&amp;language=$INFO[language]" dest="3">
+ <RegExp input="$$2" output="%20(\1)" dest="4">
+ <expression clear="yes">(.+)</expression>
+ </RegExp>
+ <expression></expression>
+ </RegExp>
+ </CreateSearchUrl>
+
+ <!-- input: $1=html $2=search query -->
+ <!-- returns: results in xml format <results><movie><title>*</title><url>*</url>*#urls<extra>*</extra></movie>*</results> -->
+ <GetSearchResults dest="1">
+ <RegExp output="\1" dest="3">
+ <expression noclean="1">&lt;Data&gt;(.*)&lt;/Data&gt;</expression>
+ </RegExp>
+ <RegExp input="$$4" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="1">
+ <RegExp input="$$3" output="&lt;entity&gt;&lt;title&gt;\3&lt;/title&gt;&lt;language&gt;\2&lt;/language&gt;&lt;url cache=&quot;\1.xml&quot;&gt;http://www.thetvdb.com/api/1D62F2F90030C444/series/\1/all/\2.zip&lt;/url&gt;&lt;id&gt;\1&lt;/id&gt;&lt;/entity&gt;" dest="4">
+ <expression repeat="yes">&lt;seriesid&gt;([0-9]*)&lt;/seriesid&gt;[^&lt;]*&lt;language&gt;([^&lt;]*)&lt;/language&gt;[^&lt;]*&lt;SeriesName&gt;([^&lt;]*)&lt;/SeriesName&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+
+ <!-- input: $1..#urls=html -->
+ <!-- input: $(#urls+1): extra !-->
+ <!-- returns: results in xml format <details><plot>*</plot><director>*</director><premiered>*</premiered><episodeguide>*</episodeguide></details> -->
+ <GetDetails dest="7">
+ <RegExp input="$$4" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;\1&lt;/details&gt;" dest="7">
+ <RegExp input="$$1" output="\1" dest="5">
+ <expression noclean="1">&lt;Series&gt;.*?&lt;id&gt;$$2&lt;/id&gt;(.*)</expression>
+ </RegExp>
+ <RegExp input="$$5" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="4">
+ <expression noclean="1">&lt;Overview&gt;([^&lt;]*)&lt;/Overview&gt;</expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;id&gt;\1&lt;/id&gt;" dest="4+">
+ <expression/>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;mpaa&gt;\1&lt;/mpaa&gt;" dest="4+">
+ <expression>&lt;ContentRating&gt;([^&lt;]*)&lt;/ContentRating&gt;</expression>
+ </RegExp>
+ <RegExp input="$$5" output="&lt;premiered&gt;\1&lt;/premiered&gt;" dest="4+">
+ <expression>&lt;FirstAired&gt;([^&lt;]*)&lt;/FirstAired&gt;</expression>
+ </RegExp>
+ <RegExp input="$$5" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="4+">
+ <expression>&lt;Rating&gt;([^&lt;]*)&lt;/Rating&gt;</expression>
+ </RegExp>
+ <RegExp input="$$5" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="4+">
+ <expression>&lt;Network&gt;([^&lt;]*)&lt;/Network&gt;</expression>
+ </RegExp>
+ <RegExp input="$$5" output="&lt;title&gt;\1&lt;/title&gt;" dest="4+">
+ <expression>&lt;SeriesName&gt;([^&lt;]*)&lt;/SeriesName&gt;</expression>
+ </RegExp>
+ <RegExp input="$$5" output="\1" dest="10">
+ <expression noclean="1">&lt;Genre&gt;([^&lt;]*)&lt;/Genre&gt;</expression>
+ </RegExp>
+ <RegExp input="$$10" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="4+">
+ <expression repeat="yes">([^\|]*)\|</expression>
+ </RegExp>
+ <RegExp input="$$10" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="4+">
+ <expression repeat="yes">([^,]*),</expression>
+ </RegExp>
+ <RegExp input="$$10" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="4+">
+ <expression>([^\|,]+)$</expression>
+ </RegExp>
+<!-- actors with thumbs -->
+ <RegExp input="$$5" output="&lt;actor&gt;&lt;name&gt;\2&lt;/name&gt;&lt;role&gt;\3&lt;/role&gt;&lt;thumb&gt;http://thetvdb.com/banners/\1&lt;/thumb&gt;&lt;/actor&gt;" dest="4+">
+ <expression repeat="yes" noclean="1,2,3">&lt;Actor&gt;.*?&lt;Image&gt;([^&lt;]+)&lt;/Image&gt;.*?&lt;Name&gt;([^&lt;]*)&lt;/Name&gt;.*?&lt;Role&gt;([^&lt;]*)</expression>
+ </RegExp>
+<!-- actors without thumbs -->
+ <RegExp input="$$5" output="&lt;actor&gt;&lt;name&gt;\2&lt;/name&gt;&lt;role&gt;\3&lt;/role&gt;&lt;/actor&gt;" dest="4+">
+ <expression repeat="yes" noclean="1,2,3">&lt;Actor&gt;.*?&lt;Image&gt;([^&lt;]*)&lt;/Image&gt;.*?&lt;Name&gt;([^&lt;]*)&lt;/Name&gt;.*?&lt;Role&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp conditional="posters" output="&lt;thumb&gt;http://thetvdb.com/banners/\1&lt;/thumb&gt;" dest="4+">
+ <expression repeat="yes">&lt;BannerPath&gt;([^&lt;]*)&lt;/BannerPath&gt;[^&lt;]*&lt;BannerType&gt;poster&lt;/BannerType&gt;</expression>
+ </RegExp>
+ <RegExp conditional="!override" input="$$5" output="&lt;thumb&gt;http://thetvdb.com/banners/\1&lt;/thumb&gt;" dest="4+">
+ <expression repeat="yes">&lt;BannerPath&gt;([^&lt;]*)&lt;/BannerPath&gt;[^&lt;]*&lt;BannerType&gt;series&lt;/BannerType&gt;[^&lt;]*&lt;BannerType2&gt;graphical&lt;/BannerType2&gt;[^&lt;]*&lt;Language&gt;$INFO[language]&lt;/Language&gt;</expression>
+ </RegExp>
+ <RegExp conditional="override" input="$$5" output="&lt;thumb&gt;http://thetvdb.com/banners/\1&lt;/thumb&gt;" dest="4+">
+ <expression repeat="yes">&lt;BannerPath&gt;([^&lt;]*)&lt;/BannerPath&gt;[^&lt;]*&lt;BannerType&gt;series&lt;/BannerType&gt;[^&lt;]*&lt;BannerType2&gt;graphical&lt;/BannerType2&gt;[^&lt;]*&lt;Language&gt;[a-z]*&lt;/Language&gt;</expression>
+ </RegExp>
+ <RegExp conditional="!override" input="$$5" output="&lt;thumb&gt;http://thetvdb.com/banners/\1&lt;/thumb&gt;" dest="4+">
+ <expression repeat="yes">&lt;BannerPath&gt;([^&lt;]*)&lt;/BannerPath&gt;[^&lt;]*&lt;BannerType&gt;series&lt;/BannerType&gt;[^&lt;]*&lt;BannerType2&gt;text&lt;/BannerType2&gt;[^&lt;]*&lt;Language&gt;$INFO[language]&lt;/Language&gt;</expression>
+ </RegExp>
+ <RegExp conditional="override" input="$$5" output="&lt;thumb&gt;http://thetvdb.com/banners/\1&lt;/thumb&gt;" dest="4+">
+ <expression repeat="yes">&lt;BannerPath&gt;([^&lt;]*)&lt;/BannerPath&gt;[^&lt;]*&lt;BannerType&gt;series&lt;/BannerType&gt;[^&lt;]*&lt;BannerType2&gt;text&lt;/BannerType2&gt;[^&lt;]*&lt;Language&gt;[a-z]*&lt;/Language&gt;</expression>
+ </RegExp>
+ <RegExp input="$$5" output="&lt;thumb&gt;http://thetvdb.com/banners/\1&lt;/thumb&gt;" dest="4+">
+ <expression repeat="yes">&lt;BannerPath&gt;([^&lt;]*)&lt;/BannerPath&gt;[^&lt;]*&lt;BannerType&gt;series&lt;/BannerType&gt;[^&lt;]*&lt;BannerType2&gt;blank&lt;/BannerType2&gt;[^&lt;]*&lt;Language&gt;&lt;/Language&gt;</expression>
+ </RegExp>
+ <RegExp conditional="!override" input="$$5" output="&lt;thumb type=&quot;season&quot; season=&quot;\2&quot;&gt;http://thetvdb.com/banners/\1&lt;/thumb&gt;" dest="4+">
+ <expression repeat="yes">&lt;BannerPath&gt;([^&lt;]*)&lt;/BannerPath&gt;[^&lt;]*&lt;BannerType&gt;season&lt;/BannerType&gt;[^&lt;]*&lt;BannerType2&gt;season&lt;/BannerType2&gt;[^&lt;]*&lt;Language&gt;$INFO[language]&lt;/Language&gt;[^&lt;]*&lt;Season&gt;([0-9]+)&lt;/Season&gt;</expression>
+ </RegExp>
+ <RegExp conditional="override" input="$$5" output="&lt;thumb type=&quot;season&quot; season=&quot;\2&quot;&gt;http://thetvdb.com/banners/\1&lt;/thumb&gt;" dest="4+">
+ <expression repeat="yes">&lt;BannerPath&gt;([^&lt;]*)&lt;/BannerPath&gt;[^&lt;]*&lt;BannerType&gt;season&lt;/BannerType&gt;[^&lt;]*&lt;BannerType2&gt;season&lt;/BannerType2&gt;[^&lt;]*&lt;Language&gt;[a-z]*&lt;/Language&gt;[^&lt;]*&lt;Season&gt;([0-9]+)&lt;/Season&gt;</expression>
+ </RegExp>
+ <RegExp conditional="!override" input="$$5" output="&lt;thumb type=&quot;season&quot; season=&quot;\2&quot;&gt;http://thetvdb.com/banners/\1&lt;/thumb&gt;" dest="4+">
+ <expression repeat="yes">&lt;BannerPath&gt;([^&lt;]*)&lt;/BannerPath&gt;[^&lt;]*&lt;BannerType&gt;season&lt;/BannerType&gt;[^&lt;]*&lt;BannerType2&gt;seasonwide&lt;/BannerType2&gt;[^&lt;]*&lt;Language&gt;$INFO[language]&lt;/Language&gt;[^&lt;]*&lt;Season&gt;([0-9]+)&lt;/Season&gt;</expression>
+ </RegExp>
+ <RegExp conditional="override" input="$$5" output="&lt;thumb type=&quot;season&quot; season=&quot;\2&quot;&gt;http://thetvdb.com/banners/\1&lt;/thumb&gt;" dest="4+">
+ <expression repeat="yes">&lt;BannerPath&gt;([^&lt;]*)&lt;/BannerPath&gt;[^&lt;]*&lt;BannerType&gt;season&lt;/BannerType&gt;[^&lt;]*&lt;BannerType2&gt;seasonwide&lt;/BannerType2&gt;[^&lt;]*&lt;Language&gt;[a-z]*&lt;/Language&gt;[^&lt;]*&lt;Season&gt;([0-9]+)&lt;/Season&gt;</expression>
+ </RegExp>
+ <RegExp input="$$5" conditional="!posters" output="&lt;thumb&gt;http://thetvdb.com/banners/\1&lt;/thumb&gt;" dest="4+">
+ <expression repeat="yes">&lt;BannerPath&gt;([^&lt;]*)&lt;/BannerPath&gt;[^&lt;]*&lt;BannerType&gt;poster&lt;/BannerType&gt;</expression>
+ </RegExp>
+ <RegExp input="$$5" output="&lt;thumb type=&quot;season&quot; season=&quot;-1&quot;&gt;http://thetvdb.com/banners/\1&lt;/thumb&gt;" dest="4+">
+ <expression repeat="yes">&lt;BannerPath&gt;([^&lt;]*)&lt;/BannerPath&gt;[^&lt;]*&lt;BannerType&gt;poster&lt;/BannerType&gt;</expression>
+ </RegExp>
+ <RegExp conditional="fanart" input="$$7" output="&lt;fanart url=&quot;http://thetvdb.com/banners/&quot;&gt;\1&lt;/fanart&gt;" dest="4+">
+ <RegExp conditional="!override" input="$$5" output="&lt;thumb dim=&quot;\2&quot; colors=&quot;\3&quot; preview=&quot;_cache/\1&quot;&gt;\1&lt;/thumb&gt;" dest="7+">
+ <expression repeat="yes">&lt;BannerPath&gt;([^&lt;]*)&lt;/BannerPath&gt;[^&lt;]*&lt;BannerType&gt;fanart&lt;/BannerType&gt;[^&lt;]*&lt;BannerType2&gt;([^&lt;]*)&lt;/BannerType2&gt;[^&lt;]*&lt;Colors&gt;([^&lt;]*)&lt;/Colors&gt;[^&lt;]*&lt;Language&gt;$INFO[language]&lt;/Language&gt;</expression>
+ </RegExp>
+ <RegExp conditional="override" input="$$5" output="&lt;thumb dim=&quot;\2&quot; colors=&quot;\3&quot; preview=&quot;_cache/\1&quot;&gt;\1&lt;/thumb&gt;" dest="7+">
+ <expression repeat="yes">&lt;BannerPath&gt;([^&lt;]*)&lt;/BannerPath&gt;[^&lt;]*&lt;BannerType&gt;fanart&lt;/BannerType&gt;[^&lt;]*&lt;BannerType2&gt;([^&lt;]*)&lt;/BannerType2&gt;[^&lt;]*&lt;Colors&gt;([^&lt;]*)&lt;/Colors&gt;[^&lt;]*&lt;Language&gt;[a-z]*&lt;/Language&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;episodeguide&gt;&lt;url cache=&quot;$$2.xml&quot;&gt;http://www.thetvdb.com/api/1D62F2F90030C444/series/\1/all/$INFO[language].zip&lt;/url&gt;&lt;/episodeguide&gt;" dest="4+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+
+ <!-- input: $1=html !-->
+ <!-- input: $2=series url !-->
+ <!-- returns: results in xml format <episodeguide><episode><title>*</title><url>*</url><season>*</season><epnum>*</epnum><thumb>*</thumb><id>*</id><aired>*</aired></episode>*</episodeguide> !-->
+ <GetEpisodeList dest="3">
+ <RegExp input="$$4" output="&lt;episodeguide&gt;\1&lt;/episodeguide&gt;" dest="3">
+ <RegExp input="$$2" output="\1" dest="10">
+ <expression>http://www.thetvdb.com/api/1D62F2F90030C444/series/([0-9]*)/all/$INFO[language].zip</expression>
+ </RegExp>
+ <!-- If Not Using "dvdorder" then check if the user wants to use "absolute ordering" -->
+ <RegExp conditional="!dvdorder">
+
+ <RegExp conditional="absolutenumber">
+ <!-- If Using "absolute ordering" then scrape episodes and return them as Season 1 and Absolute_number as Episode number -->
+ <RegExp conditional="absolutenumber" input="$$1" output="&lt;episode&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url cache=&quot;$$10.xml&quot;&gt;$$2&lt;/url&gt;&lt;epnum&gt;\4&lt;/epnum&gt;&lt;season&gt;1&lt;/season&gt;&lt;id&gt;\1&lt;/id&gt;&lt;aired&gt;\3&lt;/aired&gt;&lt;/episode&gt;" dest="4+">
+ <expression repeat="yes">&lt;Episode&gt;.*?&lt;id&gt;([0-9]*)&lt;/id&gt;.*?&lt;EpisodeName&gt;([^&lt;]*)&lt;/EpisodeName&gt;.*?&lt;FirstAired&gt;([^&lt;]*)&lt;/FirstAired&gt;.*?&lt;absolute_number&gt;([0-9]+)&lt;/absolute_number&gt;.*?&lt;/Episode&gt;</expression>
+ </RegExp>
+ <!-- If Using "absolute ordering" then scrape episodes without absolute_number with normal season/episode numbers to match Specials and other cases -->
+ <RegExp conditional="absolutenumber" input="$$1" output="&lt;episode&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url cache=&quot;$$10.xml&quot;&gt;$$2&lt;/url&gt;&lt;epnum&gt;\3&lt;/epnum&gt;&lt;season&gt;\5&lt;/season&gt;&lt;id&gt;\1&lt;/id&gt;&lt;aired&gt;\4&lt;/aired&gt;&lt;/episode&gt;" dest="4+">
+ <expression repeat="yes">&lt;Episode&gt;.*?&lt;id&gt;([0-9]+).*?&lt;EpisodeName&gt;([^&lt;]*).*?&lt;EpisodeNumber&gt;([0-9]+)[^&lt;]*.*?&lt;FirstAired&lt;([^&lt;]*)&lt;/FirstAired&gt;.*?&lt;SeasonNumber&gt;(0)&lt;/SeasonNumber&gt;.*?&lt;absolute_number&gt;&lt;/absolute_number&gt;.*?&lt;/Episode&gt;</expression>
+ </RegExp>
+ </RegExp>
+
+ <!-- If not "dvdordering" and not "absolute ordering" ... well use normal regexp ;) -->
+ <RegExp conditional="!absolutenumber" input="$$1" output="&lt;episode&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url cache=&quot;$$10.xml&quot;&gt;$$2&lt;/url&gt;&lt;epnum&gt;\3&lt;/epnum&gt;&lt;season&gt;\5&lt;/season&gt;&lt;id&gt;\1&lt;/id&gt;&lt;aired&gt;\4&lt;/aired&gt;&lt;/episode&gt;" dest="4">
+ <expression repeat="yes">&lt;Episode&gt;.*?&lt;id&gt;([0-9]+).*?&lt;EpisodeName&gt;([^&lt;]*).*?&lt;EpisodeNumber&gt;([0-9]+)[^&lt;]*.*?&lt;FirstAired&gt;([^&lt;]*)&lt;/FirstAired&gt;.*?&lt;SeasonNumber&gt;([0-9]+)[^&lt;]*.*?&lt;/Episode&gt;</expression>
+ </RegExp>
+ </RegExp>
+ <!-- ... Or use "dvdordering" -->
+ <RegExp conditional="dvdorder" input="$$1" output="&lt;episode&gt;&lt;title&gt;\4&lt;/title&gt;&lt;url cache=&quot;$$10.xml&quot;&gt;$$2&lt;/url&gt;&lt;epnum&gt;\2&lt;/epnum&gt;&lt;season&gt;\3&lt;/season&gt;&lt;id&gt;\1&lt;/id&gt;&lt;aired&gt;\5&lt;/aired&gt;&lt;/episode&gt;" dest="4">
+ <expression repeat="yes">&lt;Episode&gt;.*?&lt;id&gt;([0-9]+).*?&lt;Combined_episodenumber&gt;([0-9]+).*?&lt;Combined_season&gt;([0-9]+).*?&lt;EpisodeName&gt;([^&lt;]*).*?&lt;FirstAired&gt;([^&lt;]*)&lt;/FirstAired&gt;.*?&lt;/Episode&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetEpisodeList>
+
+ <!-- input: $1=html -->
+ <!-- returns: results in xml format <details><writer>*</writer><director>*</director><cast>*</cast><rating>*</rating><rank>*</rank><plot>*</plot> -->
+ <GetEpisodeDetails dest="3">
+ <RegExp input="$$4" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; standalone=&quot;yes&quot;?&gt;&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="\1" dest="8">
+ <expression noclean="1">&lt;Episode&gt;.*?&lt;id&gt;$$2&lt;/id&gt;(.*?)&lt;/Episode&gt;</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="4">
+ <expression>&lt;Overview&gt;([^&lt;]*)&lt;/Overview&gt;</expression>
+ </RegExp>
+ <RegExp input="$$8" output="\1" dest="6">
+ <expression noclean="1">&lt;Writer&gt;([^&lt;]*)&lt;/Writer&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="4+">
+ <expression repeat="yes">([^\|]*)\|</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="4+">
+ <expression repeat="yes">([^,]*),</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="4+">
+ <expression>([^\|,]+)$</expression>
+ </RegExp>
+ <RegExp input="$$8" output="\1" dest="6">
+ <expression noclean="1">&lt;Director&gt;([^&lt;]*)&lt;/Director&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;director&gt;\1&lt;/director&gt;" dest="4+">
+ <expression repeat="yes">([^\|]*)\|</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;director&gt;\1&lt;/director&gt;" dest="4+">
+ <expression repeat="yes">([^,]*),</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;director&gt;\1&lt;/director&gt;" dest="4+">
+ <expression>([^\|,]+)$</expression>
+ </RegExp>
+ <RegExp input="$$8" output="\1" dest="6">
+ <expression noclean="1">&lt;GuestStars&gt;([^&lt;]*)&lt;/GuestStars&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;" dest="4+">
+ <expression repeat="yes">([^\|]*)\|</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;" dest="4+">
+ <expression repeat="yes">([^,]*),</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;" dest="4+">
+ <expression>([^\|,]+)$</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;title&gt;\1&lt;/title&gt;" dest="4+">
+ <expression>&lt;EpisodeName&gt;([^&lt;]*)&lt;/EpisodeName&gt;</expression>
+ </RegExp>
+ <!-- Absolute Numbering -->
+ <RegExp conditional="absolutenumber" input="$$8" output="&lt;season&gt;1&lt;/season&gt;" dest="4+">
+ <expression></expression>
+ </RegExp>
+ <RegExp conditional="absolutenumber" input="$$8" output="&lt;episode&gt;\1&lt;/episode&gt;" dest="4+">
+ <expression>&lt;absolute_number&gt;([^&lt;]*)&lt;/absolute_number&gt;</expression>
+ </RegExp>
+ <!-- Normal Season/Episodes -->
+ <RegExp conditional="!absolutenumber" input="$$8" output="&lt;season&gt;\1&lt;/season&gt;" dest="4+">
+ <expression>&lt;SeasonNumber&gt;([^&lt;]*)&lt;/SeasonNumber&gt;</expression>
+ </RegExp>
+ <RegExp conditional="!absolutenumber" input="$$8" output="&lt;episode&gt;\1&lt;/episode&gt;" dest="4+">
+ <expression>&lt;EpisodeNumber&gt;([^&lt;]*)&lt;/EpisodeNumber&gt;</expression>
+ </RegExp>
+
+ <RegExp input="$$8" output="&lt;thumb&gt;http://thetvdb.com/banners/\1&lt;/thumb&gt;" dest="4+">
+ <expression>&lt;filename&gt;([^&lt;]+)&lt;/filename&gt;</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;aired&gt;\1&lt;/aired&gt;" dest="4+">
+ <expression>&lt;FirstAired&gt;([^&lt;]+)&lt;/FirstAired&gt;</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;displayseason&gt;\1&lt;/displayseason&gt;" dest="4+">
+ <expression>&lt;airsbefore_season&gt;([^&lt;]+)&lt;/airsbefore_season&gt;</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;displayepisode&gt;\1&lt;/displayepisode&gt;" dest="4+">
+ <expression>&lt;airsbefore_episode&gt;([^&lt;]+)&lt;/airsbefore_episode&gt;</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;displayafterseason&gt;\1&lt;/displayafterseason&gt;" dest="4+">
+ <expression>&lt;airsafter_season&gt;([^&lt;]+)&lt;/airsafter_season&gt;</expression>
+ </RegExp>
+ <RegExp input="$$8" output="&lt;rating&gt;\1&lt;/rating&gt;" dest="4+">
+ <expression>&lt;Rating&gt;([^&lt;]+)&lt;/Rating&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetEpisodeDetails>
+
+ <GetLanguages dest="3">
+ <RegExp input="$$2" output="&lt;settings&gt;&lt;setting label=&quot;Language&quot; type=&quot;labelenum&quot; id=&quot;language&quot; values=&quot;$$8&quot; sort=&quot;yes&quot; default=&quot;en&quot;&gt;&lt;/setting&gt;&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="\1|" dest="8+">
+ <expression repeat="yes">&lt;abbreviation&gt;([^&lt;]*)&lt;/abbreviation&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetLanguages>
+</scraper>
diff --git a/system/scrapers/video/tvrage.jpg b/system/scrapers/video/tvrage.jpg
new file mode 100644
index 0000000000..b8b22d6351
--- /dev/null
+++ b/system/scrapers/video/tvrage.jpg
Binary files differ
diff --git a/system/scrapers/video/tvrage.xml b/system/scrapers/video/tvrage.xml
new file mode 100644
index 0000000000..c90a929a48
--- /dev/null
+++ b/system/scrapers/video/tvrage.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.0" date="2009-05-22" name="TV Rage" content="tvshows" thumb="tvrage.jpg" language="en">
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://www.tvrage.com/search.php?search=\1&lt;/url&gt;" dest="3">
+ <expression></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="3">
+ <RegExp input="$$4" output="&lt;results&gt;\1&lt;/results&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\2&lt;/title&gt;&lt;url&gt;http://www.tvrage.com/\1&lt;/url&gt;&lt;/entity&gt;" dest="4">
+ <expression repeat="yes">&lt;td class='b1'&gt;&lt;img[^&gt;]*&gt; &lt;a[^h]*href='http://www\.tvrage\.com/([^']*)' &gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails dest="7">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="7">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression>&lt;/a&gt;&quot;([^&quot;]*)&quot; Summary&lt;/h5&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>\n&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;(.*)&lt;br&gt;&amp;nbsp;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;&lt;votes&gt;\2&lt;/votes&gt;" dest="5+">
+ <expression>&lt;strong&gt;([0-9.]+)/10 \(([0-9]*) Votes cast\)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\2&lt;/role&gt;&lt;/actor&gt;" dest="5+">
+ <expression repeat="yes">a href='/person/[^&gt;]*&gt;([^(&lt;|\(|/)]*)&lt;/a&gt;&lt;/i&gt;&lt;/span&gt;&lt;/td&gt;&lt;td[^&gt;]*&gt;&lt;b&gt;played&lt;/b&gt;&lt;/td&gt;&lt;td[^&gt;]*&gt;&lt;div[^&gt;]*&gt;&lt;i&gt;([^(&lt;|\(|/)]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="5+">
+ <expression>(http://images\.tvrage\.net/shows/[0-9/]+\.(gif|jpg|png))</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;status&gt;\1&lt;/status&gt;" dest="5+">
+ <expression trim="1">Status: &lt;/b&gt;&lt;/td&gt;&lt;td&gt;([^&lt;]*)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;premiered&gt;\1&lt;/premiered&gt;" dest="5+">
+ <expression trim="1">Premiere: &lt;/b&gt;&lt;/td&gt;&lt;td&gt;([^&lt;]*)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;runtime&gt;\1&lt;/runtime&gt;" dest="5+">
+ <expression trim="1">Runtime: &lt;/b&gt;&lt;/td&gt;&lt;td&gt;([^&lt;]*)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$6" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <RegExp input="$$1" output="| \1" dest="6">
+ <expression noclean="1">Genre: &lt;/b&gt;&lt;/td&gt;&lt;td&gt;([^&lt;]*)&lt;/td&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">\| ([^\|]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;episodeguide&gt;&lt;url&gt;http://www.tvrage.com\1all&lt;/url&gt;&lt;/episodeguide&gt;" dest="5+">
+ <expression trim="1">href='([^']*)'&gt;Episode List&lt;/a&gt;&lt;br&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+ <GetEpisodeList dest="3">
+ <RegExp input="$$5" output="&lt;episodeguide&gt;\1&lt;/episodeguide&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;episode&gt;&lt;url&gt;http://www.tvrage.com\1&lt;/url&gt;&lt;epnum&gt;\3&lt;/epnum&gt;&lt;season&gt;\2&lt;/season&gt;&lt;/episode&gt;" dest="5+">
+ <expression repeat="yes">class='b1'&gt;&lt;a href='([^']*)'&gt;([0-9]+)+x([0-9]+)&lt;/i&gt;&lt;/a&gt;&lt;/td&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetEpisodeList>
+ <GetEpisodeDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression>Title: &lt;/b&gt;&lt;/td&gt;&lt;td class='b2'&gt;([^&lt;]*)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <expression>&lt;td&gt;&lt;table width='100%'&gt;&lt;tr&gt;&lt;td valign='top'&gt;&lt;table width='100%'&gt;&lt;tr&gt;&lt;td&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;rating&gt;\1&lt;/rating&gt;&lt;votes&gt;\2&lt;/votes&gt;" dest="5+">
+ <expression>&lt;strong&gt;([0-9.]+)/10 \(([0-9]*) Votes cast\)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;aired&gt;\1&lt;/aired&gt;" dest="5+">
+ <expression>Original Airdate: &lt;/b&gt;&lt;/td&gt;&lt;td class='b2'&gt;([^&lt;]*)</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;\1&lt;/thumb&gt;" dest="5+">
+ <expression>(http://images\.tvrage\.net/screencaps/[0-9/]*\.(jpg|gif|png))</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;code&gt;\1&lt;/code&gt;" dest="5+">
+ <expression>Production Number: &lt;/b&gt;&lt;/td&gt;&lt;td class='b2'&gt;([^&lt;]*)&lt;/td&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;role&gt;\2&lt;/role&gt;&lt;/actor&gt;" dest="5+">
+ <expression repeat="yes">a href='/person/[^&gt;]*&gt;([^(&lt;|\(|/)]*)&lt;/a&gt;&lt;/i&gt;&lt;/td&gt;&lt;td[^&gt;]*&gt;&lt;b&gt;played&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;i&gt;([^(&lt;|\(|/)]*)</expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;director&gt;\1&lt;/director&gt;" dest="5+">
+ <RegExp input="$$1" output="| \1" dest="2">
+ <expression noclean="1">Director: &lt;/b&gt;&lt;/td&gt;&lt;td[^&gt;]*&gt;&lt;i&gt;&lt;a href='/person/[^&gt;]*&gt;([^(&lt;|\(|/)]*)&lt;/a&gt;&lt;/i&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">\| ([^\|]*)</expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="5+">
+ <RegExp input="$$1" output="| \1" dest="2">
+ <expression noclean="1">Writer: &lt;/b&gt;&lt;/td&gt;&lt;td[^&gt;]*&gt;&lt;i&gt;&lt;a href='/person/[^&gt;]*&gt;([^(&lt;|\(|/)]*)&lt;/a&gt;&lt;/i&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">\| ([^\|]*)</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetEpisodeDetails>
+</scraper>
diff --git a/system/scrapers/video/worldart.gif b/system/scrapers/video/worldart.gif
new file mode 100644
index 0000000000..f91a81969a
--- /dev/null
+++ b/system/scrapers/video/worldart.gif
Binary files differ
diff --git a/system/scrapers/video/worldart.xml b/system/scrapers/video/worldart.xml
new file mode 100644
index 0000000000..22a2c87c97
--- /dev/null
+++ b/system/scrapers/video/worldart.xml
@@ -0,0 +1,256 @@
+<?xml version="1.0" encoding="windows-1251" standalone="yes"?>
+<scraper framework="1.1" date="2009-09-13" content="movies" name="World Art Movies (Russian)" thumb="worldart.gif" language="ru">
+ <include>common/tmdb.xml</include>
+ <include>common/imdb.xml</include>
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Постер из TMDB (Иначе стандартный)&quot; type=&quot;bool&quot; id=&quot;thepos&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Фанарт из TMDB&quot; type=&quot;bool&quot; id=&quot;fanart&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Актеры из IMDB (Рекомендованно)&quot; type=&quot;bool&quot; id=&quot;imdbcast&quot; default=&quot;true&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Директор из IMDB&quot; type=&quot;bool&quot; id=&quot;imdbdir&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;setting label=&quot;Сценаристы из IMDB&quot; type=&quot;bool&quot; id=&quot;imdbcred&quot; default=&quot;false&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetSettings>
+
+ <CreateSearchUrl dest="3" SearchStringEncoding="CP1251">
+ <RegExp input="$$1" output="http://www.world-art.ru/search.php?name=\1&amp;global_sector=all" dest="3">
+ <expression noclean="1"/>
+ </RegExp>
+ </CreateSearchUrl>
+
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;windows-1251&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\4&lt;/title&gt;&lt;url&gt;http://www.world-art.ru/\1/\1.php?id=\3&lt;/url&gt;&lt;id&gt;\3&lt;/id&gt;&lt;/entity&gt;" dest="5+">
+ <expression repeat="yes">&quot;([^/]+)/([^=]+)=([^&quot;]+)&quot; class=&apos;estimation&apos;&gt;([^&lt;]+)&lt;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetSearchResults>
+
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <!-- ID -->
+ <RegExp input="$$2" output="&lt;id&gt;\1&lt;/id&gt;" dest="5">
+ <expression/>
+ </RegExp>
+ <!-- TITLE -->
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5+">
+ <expression trim="1">name=&apos;description&apos; content=&apos;([^&apos;]+)&apos;</expression>
+ </RegExp>
+
+ <!-- TYPE -->
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression trim="1">/([^/]+)/review.php</expression>
+ </RegExp>
+
+ <!-- MPAA -->
+ <RegExp input="$$1" output="&lt;url cache=&quot;\1-imdb.html&quot; function=&quot;MPAA&quot;&gt;http://www.imdb.com/title/tt\1&lt;/url&gt;" dest="5+">
+ <expression>imdb.com/title/tt([0-9]*)</expression>
+ </RegExp>
+
+ <!-- TOP250 -->
+ <RegExp input="$$1" output="&lt;url cache=&quot;\1-imdb.html&quot; function=&quot;TOP&quot;&gt;http://www.imdb.com/title/tt\1&lt;/url&gt;" dest="5+">
+ <expression>imdb.com/title/tt([0-9]*)</expression>
+ </RegExp>
+
+ <!-- YEAR -->
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>year=([^&quot;]+)&quot;</expression>
+ </RegExp>
+
+ <!-- RUNTIME -->
+ <RegExp input="$$1" output="&lt;runtime&gt;\1 min&lt;/runtime&gt;" dest="5+">
+ <expression noclean="1">полнометражный фильм, ([^м]+) мин</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url cache=&quot;\1-imdb.html&quot; function=&quot;RUNTIME&quot;&gt;http://www.imdb.com/title/tt\1&lt;/url&gt;" dest="5+">
+ <expression noclean="1" clear="no">imdb.com/title/tt([0-9]*)</expression>
+ </RegExp>
+
+ <!-- RATING -->
+ <RegExp input="$$1" output="&lt;url function=&quot;GetRating&quot;&gt;http://www.world-art.ru/$$7/votes_history.php?id=$$2&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;url cache=&quot;\1-imdb.html&quot; function=&quot;GetRatingAndVotes&quot;&gt;http://www.imdb.com/title/tt\1&lt;/url&gt;" dest="5+">
+ <expression noclean="1" clear="no">imdb.com/title/tt([0-9]*)</expression>
+ </RegExp>
+
+ <!-- GENRE -->
+ <RegExp input="$$1" output="&lt;genre&gt;\2&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes">genre=([^&gt;]+)&gt;([^&lt;]+)&lt;</expression>
+ </RegExp>
+
+ <!-- STUDIO -->
+ <RegExp input="$$1" output="&lt;url function=&quot;GetStudios&quot;&gt;http://www.world-art.ru/$$7/$$7_full_production.php?id=$$2&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+
+ <RegExp input="$$1" output="&lt;url cache=&quot;\1-imdb.html&quot; function=&quot;GetIMDBStudios&quot;&gt;http://www.imdb.com/title/tt\1&lt;/url&gt;" dest="5+">
+ <expression noclean="1" clear="no">imdb.com/title/tt([0-9]*)</expression>
+ </RegExp>
+
+ <!-- DIRECTORS, WRITERS, ACTORS -->
+ <RegExp input="$$2" output="&lt;url function=&quot;GetPeople&quot;&gt;http://www.world-art.ru/$$7/$$7_full_cast.php?id=$$2&lt;/url&gt;" dest="5+">
+ <expression/>
+ </RegExp>
+ <RegExp conditional="imdbcast" input="$$1" output="&lt;url cache=&quot;\1-fullcredits.html&quot; function=&quot;GetIMDBCast&quot;&gt;http://www.imdb.com/title/tt\1/fullcredits&lt;/url&gt;"dest="5+">
+ <expression noclean="1" clear="no">imdb.com/title/tt([0-9]*)</expression>
+ </RegExp>
+ <RegExp conditional="imdbdir" input="$$1" output="&lt;url cache=&quot;\1-fullcredits.html&quot; function=&quot;GetIMDBDirectors&quot;&gt;http://www.imdb.com/title/tt\1/fullcredits&lt;/url&gt;"dest="5+">
+ <expression noclean="1" clear="no">imdb.com/title/tt([0-9]*)</expression>
+ </RegExp>
+ <RegExp conditional="imdbcred" input="$$1" output="&lt;url cache=&quot;\1-fullcredits.html&quot; function=&quot;GetIMDBCastWriters&quot;&gt;http://www.imdb.com/title/tt\1/fullcredits&lt;/url&gt;"dest="5+">
+ <expression noclean="1" clear="no">imdb.com/title/tt([0-9]*)</expression>
+ </RegExp>
+
+ <!-- OUTLINE, PLOT -->
+ <RegExp input="$$1" output="\1&amp;#133;&amp;hellip;&amp;laquo;&amp;#151;&amp;mdash;&amp;nbsp;" dest="2">
+ <expression noclean="1">class=&apos;review&apos;&gt;[\t\n]*(.*?)[\t\n]*&lt;/p&gt;</expression>
+ </RegExp>
+ <RegExp input="$$2" output="&lt;outline&gt;\1&lt;/outline&gt;&lt;plot&gt;\1&lt;/plot&gt;" dest="5+">
+ <RegExp input="$$2" output="\1 " dest="2">
+ <expression noclean="1" repeat="yes">(.*?)&amp;nbsp;</expression>
+ </RegExp>
+ <RegExp input="$$2" output="\1-" dest="2">
+ <expression noclean="1" repeat="yes">(.*?)&amp;mdash;</expression>
+ </RegExp>
+ <RegExp input="$$2" output="\1-" dest="2">
+ <expression noclean="1" repeat="yes">(.*?)&amp;#151;</expression>
+ </RegExp>
+ <RegExp input="$$2" output="\1&quot;" dest="2">
+ <expression noclean="1" repeat="yes">(.*?)&amp;[lr]aquo;</expression>
+ </RegExp>
+ <RegExp input="$$2" output="\1..." dest="2">
+ <expression noclean="1" repeat="yes">(.*?)&amp;hellip;</expression>
+ </RegExp>
+ <RegExp input="$$2" output="\1..." dest="2">
+ <expression noclean="1" repeat="yes">(.*?)&amp;#133;</expression>
+ </RegExp>
+ <expression trim="1">(.*)\.{3}?</expression>
+ </RegExp>
+
+ <!-- THUMBS -->
+ <RegExp input="$$1" output="&lt;url function=&quot;GetCoverThumbs&quot;&gt;http://www.world-art.ru/$$7/$$7_poster.php?id=\1&lt;/url&gt;" dest="5+">
+ <expression noclean="1">id=([0-9]*)&gt;</expression>
+ </RegExp>
+ <RegExp conditional="thepos" input="$$1" output="&lt;url function=&quot;GetTMDBThumbsByIMDBId&quot;&gt;http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=tt\1&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="5+">
+ <expression noclean="1" clear="no">imdb.com/title/tt([0-9]*)</expression>
+ </RegExp>
+
+ <!-- FANART -->
+ <RegExp conditional="fanart" input="$$1" output="&lt;url function=&quot;GetTMDBFanartByIMDBId&quot;&gt;http://api.themoviedb.org/2.0/Movie.imdbLookup?imdb_id=tt\1&amp;amp;api_key=57983e31fb435df4df77afb854740ea9&lt;/url&gt;" dest="5+">
+ <expression>imdb.com/title/tt([0-9]*)</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetDetails>
+
+ <!-- MPAA -->
+ <MPAA dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;mpaa&gt;\1&lt;/mpaa&gt;&lt;/details&gt;" dest="5+">
+ <expression trim="1">MPAA&lt;/a&gt;:&lt;/h5&gt;(.[^&lt;]*)</expression>
+ </RegExp>
+ </MPAA>
+
+ <!-- TOP250 -->
+ <TOP dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;top250&gt;\1&lt;/top250&gt;&lt;/details&gt;" dest="5+">
+ <expression trim="1">Top 250: #([0-9]*)&lt;/a&gt;</expression>
+ </RegExp>
+ </TOP>
+
+ <!-- RUNTIME -->
+ <RUNTIME dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;runtime&gt;\1&lt;/runtime&gt;&lt;/details&gt;" dest="5+">
+ <expression trim="1">&lt;h5&gt;Runtime:&lt;/h5&gt;[^0-9]*([^&lt;]*)</expression>
+ </RegExp>
+ </RUNTIME>
+
+ <!-- RATINGS -->
+ <GetRating dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;rating&gt;\1&lt;/rating&gt;&lt;votes&gt;10&lt;/votes&gt;&lt;/details&gt;" dest="5+">
+ <expression trim="1">Средний рейтинг:&lt;/b&gt; ([^,]+),</expression>
+ </RegExp>
+ </GetRating>
+
+ <GetRatingAndVotes dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;rating&gt;\1&lt;/rating&gt;&lt;votes&gt;\2&lt;/votes&gt;&lt;/details&gt;" dest="5+">
+ <expression trim="1">&lt;b&gt;([0-9.]+)/10&lt;/b&gt;[^&lt;]*&lt;a href=&quot;ratings&quot; class=&quot;tn15more&quot;&gt;([0-9,]+) votes&lt;/a&gt;</expression>
+ </RegExp>
+ </GetRatingAndVotes>
+
+ <!-- STUDIOS -->
+ <GetStudios dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;studio&gt;\1&lt;/studio&gt;&lt;/details&gt;" dest="5+">
+ <expression repeat="yes">class=&apos;estimation&apos;&gt;([^&lt;]+)&lt;</expression>
+ </RegExp>
+ </GetStudios>
+
+ <GetIMDBStudios dest="5">
+ <RegExp input="$$1" output="&lt;details&gt;&lt;studio&gt;\1&lt;/studio&gt;&lt;/details&gt;" dest="5+">
+ <expression repeat="yes">&quot;/company/[^/]*/&quot;&gt;([^&lt;]*)&lt;/a&gt;</expression>
+ </RegExp>
+ </GetIMDBStudios>
+
+ <!-- ACTORS -->
+ <GetPeople dest="5">
+ <RegExp input="$$7" output="&lt;details&gt;\1&lt;/details&gt;" dest="5+">
+ <RegExp input="$$8" output="&lt;actor&gt;&lt;name&gt;\1&lt;/name&gt;&lt;/actor&gt;" dest="7+">
+ <RegExp input="$$1" output="\1" dest="8+">
+ <expression noclean="1">В ролях:(.*?)bgcolor=#5D0E0E</expression>
+ </RegExp>
+ <expression repeat="yes">class=&apos;estimation&apos;&gt;([^&lt;]+)&lt;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetPeople>
+
+ <!-- DIRECTORS -->
+ <GetDirector dest="5">
+ <RegExp input="$$7" output="&lt;details&gt;\1&lt;/details&gt;" dest="5+">
+ <RegExp input="$$8" output="&lt;director&gt;\1&lt;/director&gt;" dest="7+">
+ <RegExp input="$$1" output="\1" dest="8+">
+ <expression noclean="1"> color=#990000(.*?) color=#990000</expression>
+ </RegExp>
+ <expression repeat="yes">class=&apos;estimation&apos;&gt;([^&lt;]+)&lt;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetDirector>
+
+ <!-- WRITERS -->
+ <GetCredits dest="5">
+ <RegExp input="$$7" output="&lt;details&gt;\1&lt;/details&gt;" dest="5+">
+ <RegExp input="$$8" output="&lt;credits&gt;\1&lt;/credits&gt;" dest="7+">
+ <RegExp input="$$1" output="\1" dest="8+">
+ <expression noclean="1">Сценарий:(.*?):&lt;/b&gt;</expression>
+ </RegExp>
+ <expression repeat="yes">class=&apos;estimation&apos;&gt;([^&lt;]+)&lt;</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetCredits>
+
+ <!-- POSTERS -->
+ <GetCoverThumbs dest="5">
+ <RegExp input="$$8" output="&lt;details&gt;\1&lt;/details&gt;" dest="5+">
+ <RegExp input="$$1" output="\1" dest="7">
+ <expression trim="1">/([^/]+)/review.php</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb preview=&quot;http://www.world-art.ru/$$7/img/\1/\3/\4.jpg&quot;&gt;http://www.world-art.ru/$$7/img/\1/\3/\4.jpg&lt;/thumb&gt;" dest="8+">
+ <expression repeat="yes" noclean="1">img/converted_images_(.*?)/(.*?)/(.*?)-(.*?)-(.*?)</expression>
+ </RegExp>
+ <expression noclean="1"/>
+ </RegExp>
+ </GetCoverThumbs>
+</scraper>
diff --git a/system/scrapers/video/yahoomusic.png b/system/scrapers/video/yahoomusic.png
new file mode 100644
index 0000000000..007c422028
--- /dev/null
+++ b/system/scrapers/video/yahoomusic.png
Binary files differ
diff --git a/system/scrapers/video/yahoomusic.xml b/system/scrapers/video/yahoomusic.xml
new file mode 100644
index 0000000000..b8c3138bd9
--- /dev/null
+++ b/system/scrapers/video/yahoomusic.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<scraper framework="1.0" date="2009-05-22" name="Yahoo! Music" content="musicvideos" thumb="yahoomusic.png" language="en">
+ <GetSettings dest="3">
+ <RegExp input="$$5" output="&lt;settings&gt;\1&lt;/settings&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;setting label=&quot;Thumb(s) Size&quot; type=&quot;labelenum&quot; values=&quot;192|256|384|512|1024&quot; id=&quot;yahooscale&quot; default=&quot;384&quot;&gt;&lt;/setting&gt;" dest="5+">
+ <expression></expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSettings>
+ <CreateSearchUrl dest="3">
+ <RegExp input="$$1" output="&lt;url&gt;http://us.music.yahooapis.com/video/v1/list/search/all/\1?appid=r6QWQGXV34H0Sl3Wq4vWJI2v9IO1XnZw5JkeifPbTq2p0S9H9kg0JUc3SVN0Yw--&amp;amp;response=artists,images&lt;/url&gt;" dest="3">
+ <expression noclean="1"></expression>
+ </RegExp>
+ </CreateSearchUrl>
+ <GetSearchResults dest="8">
+ <RegExp input="$$5" output="&lt;?xml version=&quot;1.0&quot; encoding=&quot;iso-8859-1&quot; standalone=&quot;yes&quot;?&gt;&lt;results&gt;\1&lt;/results&gt;" dest="8">
+ <RegExp input="$$1" output="&lt;entity&gt;&lt;title&gt;\4 - \1 (\2)&lt;/title&gt;&lt;url&gt;http://us.music.yahooapis.com/video/v1/item/\3?format=xml&amp;amp;appid=r6QWQGXV34H0Sl3Wq4vWJI2v9IO1XnZw5JkeifPbTq2p0S9H9kg0JUc3SVN0Yw--&lt;/url&gt;&lt;/entity&gt;" dest="5">
+ <expression repeat="yes">&lt;Video.*?title=&quot;([^&quot;]*)&quot;.*?copyrightYear=&quot;([^&quot;]*)&quot;.*?\/([0-9]*)\?size.*?name=&quot;([^&quot;]*)&quot;.*?&lt;/Video&gt;</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetSearchResults>
+ <GetDetails dest="3">
+ <RegExp input="$$5" output="&lt;details&gt;\1&lt;/details&gt;" dest="3">
+ <RegExp input="$$1" output="&lt;title&gt;\1&lt;/title&gt;" dest="5">
+ <expression>&lt;Video.*?title=&quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;artist&gt;\1&lt;/artist&gt;" dest="5+">
+ <expression repeat="yes">&lt;Artist.*?name=&quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;album&gt;\1&lt;/album&gt;" dest="5+">
+ <expression>&lt;Release.*?title=&quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;studio&gt;\1&lt;/studio&gt;" dest="5+">
+ <expression repeat="yes">label=&quot;([^&quot;]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;year&gt;\1&lt;/year&gt;" dest="5+">
+ <expression>copyrightYear=&quot;([0-9]*)&quot;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;genre&gt;\1&lt;/genre&gt;" dest="5+">
+ <expression repeat="yes">&lt;Category.*?name=&quot;([^&quot;]*)&quot; rating=&quot;([^&quot;]*)&quot; type=&quot;Genre&quot;&gt;</expression>
+ </RegExp>
+ <RegExp input="$$1" output="&lt;thumb&gt;http://d.yimg.com/img.music.yahoo.com/image/v1/video/\1?size=$INFO[yahooscale]&lt;/thumb&gt;" dest="5+">
+ <expression>\/([0-9]*)\?size</expression>
+ </RegExp>
+ <expression noclean="1"></expression>
+ </RegExp>
+ </GetDetails>
+</scraper>
diff --git a/system/shaders/yuv2rgb_basic.glsl b/system/shaders/yuv2rgb_basic.glsl
new file mode 100644
index 0000000000..49fdf633a5
--- /dev/null
+++ b/system/shaders/yuv2rgb_basic.glsl
@@ -0,0 +1,28 @@
+#if(XBMC_texture_rectangle)
+# extension GL_ARB_texture_rectangle : enable
+# define texture2D texture2DRect
+# define sampler2D sampler2DRect
+#endif
+
+uniform sampler2D m_sampY;
+uniform sampler2D m_sampU;
+uniform sampler2D m_sampV;
+varying vec2 m_cordY;
+varying vec2 m_cordU;
+varying vec2 m_cordV;
+
+uniform mat4 m_yuvmat;
+
+
+void main()
+{
+ vec4 yuv, rgb;
+ yuv.rgba = vec4( texture2D(m_sampY, m_cordY).r
+ , texture2D(m_sampU, m_cordU).r
+ , texture2D(m_sampV, m_cordV).r
+ , 1.0 );
+
+ rgb = m_yuvmat * yuv;
+ rgb.a = gl_Color.a;
+ gl_FragColor = rgb;
+}
diff --git a/system/shaders/yuv2rgb_basic_2d.arb b/system/shaders/yuv2rgb_basic_2d.arb
new file mode 100644
index 0000000000..d37d3ff8bd
--- /dev/null
+++ b/system/shaders/yuv2rgb_basic_2d.arb
@@ -0,0 +1,13 @@
+!!ARBfp1.0
+PARAM yuvmat[4] = { program.local[0..3] };
+TEMP R0;
+TEMP R1;
+TEX R0.x, fragment.texcoord[0], texture[0], 2D;
+TEX R0.y, fragment.texcoord[1], texture[1], 2D;
+TEX R0.z, fragment.texcoord[2], texture[2], 2D;
+DPH R1.r, R0, yuvmat[0];
+DPH R1.g, R0, yuvmat[1];
+DPH R1.b, R0, yuvmat[2];
+MOV R1.a, fragment.color.a;
+MOV result.color, R1;
+END
diff --git a/system/shaders/yuv2rgb_basic_rect.arb b/system/shaders/yuv2rgb_basic_rect.arb
new file mode 100644
index 0000000000..82588a0080
--- /dev/null
+++ b/system/shaders/yuv2rgb_basic_rect.arb
@@ -0,0 +1,13 @@
+!!ARBfp1.0
+PARAM yuvmat[4] = { program.local[0..3] };
+TEMP R0;
+TEMP R1;
+TEX R0.x, fragment.texcoord[0], texture[0], RECT;
+TEX R0.y, fragment.texcoord[1], texture[1], RECT;
+TEX R0.z, fragment.texcoord[2], texture[2], RECT;
+DPH R1.r, R0, yuvmat[0];
+DPH R1.g, R0, yuvmat[1];
+DPH R1.b, R0, yuvmat[2];
+MOV R1.a, fragment.color.a;
+MOV result.color, R1;
+END
diff --git a/system/shaders/yuv2rgb_bob.glsl b/system/shaders/yuv2rgb_bob.glsl
new file mode 100644
index 0000000000..c5901c766c
--- /dev/null
+++ b/system/shaders/yuv2rgb_bob.glsl
@@ -0,0 +1,44 @@
+#if(XBMC_texture_rectangle)
+# extension GL_ARB_texture_rectangle : enable
+# define texture2D texture2DRect
+# define sampler2D sampler2DRect
+#endif
+
+uniform sampler2D m_sampY;
+uniform sampler2D m_sampU;
+uniform sampler2D m_sampV;
+varying vec2 m_cordY;
+varying vec2 m_cordU;
+varying vec2 m_cordV;
+
+uniform mat4 m_yuvmat;
+
+uniform float m_stepX;
+uniform float m_stepY;
+uniform int m_field;
+
+void main()
+{
+ vec4 yuv, rgb;
+
+ vec2 offsetY;
+ vec2 offsetU;
+ vec2 offsetV;
+ float temp1 = mod(m_cordY.y, 2*m_stepY);
+
+ offsetY = m_cordY;
+ offsetU = m_cordU;
+ offsetV = m_cordV;
+
+ offsetY.y -= (temp1 - m_stepY/2 + float(m_field)*m_stepY);
+ offsetU.y -= (temp1 - m_stepY/2 + float(m_field)*m_stepY)/2;
+ offsetV.y -= (temp1 - m_stepY/2 + float(m_field)*m_stepY)/2;
+
+ yuv.rgba = vec4( texture2D(m_sampY, offsetY).r
+ , texture2D(m_sampU, offsetU).r
+ , texture2D(m_sampV, offsetV).r
+ , 1.0);
+ rgb = m_yuvmat * yuv;
+ rgb.a = gl_Color.a;
+ gl_FragColor = rgb;
+}
diff --git a/system/shaders/yuv2rgb_vertex.glsl b/system/shaders/yuv2rgb_vertex.glsl
new file mode 100644
index 0000000000..f32caccf4a
--- /dev/null
+++ b/system/shaders/yuv2rgb_vertex.glsl
@@ -0,0 +1,18 @@
+varying vec2 m_cordY;
+varying vec2 m_cordU;
+varying vec2 m_cordV;
+
+void main()
+{
+#if(XBMC_texture_rectangle_hack)
+ m_cordY = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0 / 2);
+ m_cordU = vec2(gl_TextureMatrix[1] * gl_MultiTexCoord1 * 2);
+ m_cordV = vec2(gl_TextureMatrix[2] * gl_MultiTexCoord2);
+#else
+ m_cordY = vec2(gl_TextureMatrix[0] * gl_MultiTexCoord0);
+ m_cordU = vec2(gl_TextureMatrix[1] * gl_MultiTexCoord1);
+ m_cordV = vec2(gl_TextureMatrix[2] * gl_MultiTexCoord2);
+#endif
+ gl_Position = ftransform();
+ gl_FrontColor = gl_Color;
+}