Index: ipk/source/epg_crossepg_0_61/var/crossepg/crossepg.config
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/crossepg.config	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/crossepg.config	(revision 6505)
@@ -0,0 +1,17 @@
+db_root=/media/autofs/NAS/crossepg
+lamedb=lamedb
+providers=rytec_erotic_xmltv|rytec_germany_austria_swiss_xmltv|krkadoni_dplus_xepgdb
+force_load_on_boot=1
+download_daily_enabled=0
+download_daily_hours=4
+download_daily_minutes=0
+download_daily_reboot=1
+download_tune_enabled=0
+download_manual_reboot=0
+download_standby_enabled=0
+last_full_download_timestamp=0
+last_partial_download_timestamp=0
+csv_import_enabled=0
+show_plugin=1
+show_extension=1
+configured=1
Index: ipk/source/epg_crossepg_0_61/var/crossepg/crossepg_epgmove.sh
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/crossepg_epgmove.sh	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/crossepg_epgmove.sh	(revision 6505)
@@ -0,0 +1,21 @@
+#!/bin/sh
+HOME=`echo $0 | sed "s/crossepg_epgmove\.sh//"`
+
+if [ -f "$HOME/crossepg.config" ] # if configuration exist
+then
+	DBROOT=`cat $HOME/crossepg.config | grep db_root= | sed "s/db_root=//"`
+else # else default path
+	DBROOT="/hdd/crossepg"
+fi
+
+if [ -f "$DBROOT/ext.epg.dat" ] # try on configuration path
+then
+	echo copying ext.epg.dat from $DBROOT
+	$HOME/crossepg_epgcopy "$DBROOT/ext.epg.dat" /hdd/epg.dat
+elif [ -f "/hdd/crossepg/ext.epg.dat" ] # if we have a bad path try with default path
+then
+	echo copying ext.epg.dat from /hdd/crossepg/
+	$HOME/crossepg_epgcopy /hdd/crossepg/ext.epg.dat /hdd/epg.dat
+else # no epg found
+	echo ext.epg.dat not found
+fi
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/alias_script.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/alias_script.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/alias_script.conf	(revision 6505)
@@ -0,0 +1,3 @@
+protocol=script
+filename=alias/alias.py
+description=ALIAS: do simple aliases handling
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/ausat_optusc1_156.0.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/ausat_optusc1_156.0.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/ausat_optusc1_156.0.conf	(revision 6505)
@@ -0,0 +1,13 @@
+description=Ausat OpenTV (Optusc1 on 156.0)
+# nid ,tsid, sid
+nid=4096
+tsid=17
+sid=17008
+namespace=102236160
+# channels pids
+channels_pids=17
+# titles pids
+titles_pids=48|49|50|51|52|53|54|55
+# summaries pids
+summaries_pids=64|65|66|67|68|69|70|71
+protocol=opentv
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/ausat_optusc1_156.0.dict
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/ausat_optusc1_156.0.dict	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/ausat_optusc1_156.0.dict	(revision 6505)
@@ -0,0 +1,512 @@
+ =101010111000110000101001100
+ =101010111000110000101001101
+ =101010111000110000101001110
+ =101010111000110000101001111
+ =101010111000110000101010000
+ =101010111000110000101010001
+ =101010111000110000101010010
+ =101010111000110000101010011
+ =101010111000110000101010100
+=0001000
+ =1110111
+ =101010111000110000101010101
+ =101010111000110000101010110
+ =101010111000110000101010111
+ =101010111000110000101011000
+ =101010111000110000101011001
+ =101010111000110000101011010
+ =101010111000110000101011011
+ =101010111000110000101011100
+ =101010111000110000101011101
+ =101010111000110000101011110
+ =101010111000110000101011111
+ =101010111000110000101100000
+ =101010111000110000101100001
+ =101010111000110000101100010
+ =101010111000110000101100011
+ =101010111000110000101100100
+ =101010111000110000101100101
+ =101010111000110000101100110
+ =101010111000110000101100111
+ =101010111000110000101101000
+ =101010111000110000101101001
+ =110
+!=01000011000
+"=101010111000110000101101010
+#=101010111000110000101101011
+$=1010101110001101
+%=101010111000110000101101100
+&=10000011101
+'=10000010
+(=11101000101
+)=1010101100
+*=100010101110
++=101010111000110000101101101
+,=1011000
+-=10001011
+.=1110110
+/=00010100011110
+0=111010010
+1=101100111
+2=1000101000
+3=1000001111
+4=0001010000
+5=1110101000
+6=1000101001
+7=1000100010
+8=10001010110
+9=0100001101
+:=11101000110
+;=00010100010
+<=1110100011111
+==101010111000110000101101110
+>=1110101001100
+?=111010100111
+@=101010111000110001
+A=11100010
+B=01000000
+C=01000010
+D=111000111
+E=1110100000
+F=101010100
+G=100010000
+H=101010101
+I=1110100001
+J=000101001
+K=1110100111
+L=100000110
+M=10001001
+N=111010111
+O=010000010
+P=00010101
+Q=1000101010111
+R=111010110
+S=0001001
+T=0001011
+U=10101011101
+V=11101010101
+W=10110010
+X=1110001101101111
+Y=10101011110
+Z=1110101010000
+[=10101011100011001
+\=101010111000110000101101111
+]=11100011011011100
+^=101010111000110000101110000
+_=101010111000110000101110001
+`=11101010010
+a=1001
+b=1110000
+c=111001
+d=01001
+e=1111
+f=100001
+g=100011
+h=10111
+i=0101
+j=11100011010
+k=1000000
+l=10100
+m=101011
+n=0111
+o=0011
+p=000111
+q=10101011011
+r=0010
+s=0000
+t=0110
+u=101101
+v=1010100
+w=000110
+x=1110101011
+y=010001
+z=1011001100
+{=101010111000110000101110010
+|=101010111000110000101110011
+}=101010111000110000101110100
+~=101010111000110000101110101
+ =101010111000110000101110110
+ =101010111000110000101110111
+ =101010111000110000101111000
+ =101010111000110000101111001
+ =101010111000110000101111010
+ =101010111000110000101111011
+ =101010111000110000101111100
+ =101010111000110000101111101
+ =101010111000110000101111110
+ =101010111000110000101111111
+ =101010111000110000110000000
+ =101010111000110000110000001
+ =101010111000110000110000010
+ =101010111000110000110000011
+ =101010111000110000110000100
+ =101010111000110000110000101
+ =101010111000110000110000110
+ =101010111000110000110000111
+ =101010111000110000110001000
+ =101010111000110000110001001
+ =101010111000110000110001010
+ =101010111000110000110001011
+ =101010111000110000110001100
+ =101010111000110000110001101
+ =101010111000110000110001110
+ =101010111000110000110001111
+ =101010111000110000110010000
+ =101010111000110000110010001
+ =101010111000110000110010010
+ =11100011011011101
+ =101010111000110000110010011
+ =101010111000110000110010100
+ =101010111000110000110010101
+ =101010111000110000110010110
+¡=101010111000110000110010111
+¢=101010111000110000110011000
+£=101010111000110000110011001
+¤=101010111000110000110011010
+¥=101010111000110000110011011
+¦=101010111000110000110011100
+§=101010111000110000110011101
+¨=101010111000110000110011110
+©=101010111000110000110011111
+ª=101010111000110000110100000
+«=101010111000110000110100001
+¬=101010111000110000110100010
+­=101010111000110000110100011
+®=101010111000110000110100100
+¯=101010111000110000110100101
+°=101010111000110000110100110
+±=101010111000110000110100111
+²=101010111000110000110101000
+³=101010111000110000110101001
+´=101010111000110000110101010
+µ=101010111000110000110101011
+¶=101010111000110000110101100
+·=101010111000110000110101101
+¸=101010111000110000110101110
+¹=101010111000110000110101111
+º=101010111000110000110110000
+»=101010111000110000110110001
+¼=101010111000110000110110010
+½=101010111000110000110110011
+¾=101010111000110000110110100
+¿=101010111000110000110110101
+À=101010111000110000110110110
+Á=101010111000110000110110111
+Â=101010111000110000110111000
+Ã=101010111000110000110111001
+Ä=101010111000110000110111010
+Å=101010111000110000110111011
+Æ=101010111000110000110111100
+Ç=101010111000110000110111101
+È=101010111000110000110111110
+É=101010111000110000110111111
+Ê=101010111000110000111000000
+Ë=101010111000110000111000001
+Ì=101010111000110000111000010
+Í=101010111000110000111000011
+Î=101010111000110000111000100
+Ï=101010111000110000111000101
+Ð=101010111000110000111000110
+Ñ=101010111000110000111000111
+Ò=101010111000110000111001000
+Ó=101010111000110000111001001
+Ô=101010111000110000111001010
+Õ=101010111000110000111001011
+Ö=101010111000110000111001100
+×=101010111000110000111001101
+Ø=101010111000110000111001110
+Ù=101010111000110000111001111
+Ú=101010111000110000111010000
+Û=101010111000110000111010001
+Ü=101010111000110000111010010
+Ý=101010111000110000111010011
+Þ=101010111000110000111010100
+ß=101010111000110000111010101
+à=101010111000110000111010110
+á=101010111000110000111010111
+â=101010111000110000111011000
+ã=101010111000110000111011001
+ä=101010111000110000111011010
+å=101010111000110000111011011
+æ=101010111000110000111011100
+ç=101010111000110000111011101
+è=101010111000110000111011110
+é=101010111000110000111011111
+ê=101010111000110000111100000
+ë=101010111000110000111100001
+ì=101010111000110000111100010
+í=101010111000110000111100011
+î=101010111000110000111100100
+ï=101010111000110000111100101
+ð=101010111000110000111100110
+ñ=101010111000110000111100111
+ò=101010111000110000111101000
+ó=101010111000110000111101001
+ô=101010111000110000111101010
+õ=101010111000110000111101011
+ö=101010111000110000111101100
+÷=101010111000110000111101101
+ø=101010111000110000111101110
+ù=101010111000110000111101111
+ú=101010111000110000111110000
+û=101010111000110000111110001
+ü=101010111000110000111110010
+ý=101010111000110000111110011
+þ=101010111000110000111110100
+ÿ=101010111000110000111110101
+(Including =10101011111110
+(New Series)=11101000100010
+(Part =1110100011101
+(Repeat)=1110100110
+(Stereo)=010000111
+(Stereo) (Teletext)=010000011
+(Teletext)=1110001100
+(Widescreen)=100000111001110
+Action=101010111000111
+Adventures=10110011011111
+America=0100001100100
+Animated=111010100110111
+Australia=0100001100101
+Away=11101010100010
+BBC=10101011111111
+Baby=11100011011000
+Best=11101010100011
+Big=10110011011000
+Bill=1000101011111
+Black=1000101010000
+Blue=1011001101110
+Breakfast=000101000110
+Britain=1010101111100
+British=1110100011100
+Business=0100001100110
+Call=1010101111101
+Cartoon=10101011100000
+Channel=10101011100001
+Children=11101010100111
+Clock=11100011011001
+Comedy=11101000100011
+Cook=111010101001010
+Country=111010100110110
+Directed by =101010110100
+Drama=0100001100111
+East=1000101010001
+Education=100000111001111
+English=00010100011111
+Europe=0001010001110
+Extra=10110011011001
+Final=10101011100010
+Financial=111000110110100
+For=111000110111
+French=11101000111101
+From=1000101010010
+George=1010101111110
+Get=1000100011010
+Girls=10001000110110
+Golden=10001000110111
+Golf=111010101001011
+Good=1010101101010
+Great=11101000100100
+Hampshire=111010101001100
+Headlines=1000101010011
+Hear=11101010011010
+Hill=1000001110000
+Hollywood=111000110110101
+Home=1000101010100
+Hour=11101000100101
+House=1000001110010
+How=1010101101011
+ITN=11101010100100
+Important=111010101001101
+Including=1000101011110
+International=11101000100110
+John=10001000111
+Last=11101000100111
+Late=10000011100110
+Learn=10001010101100
+Little=10001010101101
+Live=1110100010000
+London=11101000111100
+Look=10110011011110
+Lunch=111000110110110
+Man=1000101010101
+Mark=1000001110001
+Meridian=101010111001
+Michael=1011001101101
+Minutes=101010111000110000111110110
+More=101010111000110000111110111
+Morning=101010111000110000111111000
+Murder=101010111000110000111111001
+Nation=101010111000110000111111010
+Neighbours=101010111000110000111111011
+New=101010111000110000111111100
+News & Weather=101010111000110000111111101
+News And Weather=101010111000110000111111110
+Paul=101010111000110000111111111
+Plus=10101011100011000000000000
+Prayer=10101011100011000000000001
+Present=10101011100011000000000010
+Presented by=10101011100011000000000011
+Quiz=10101011100011000000000100
+Regional=10101011100011000000000101
+Represent=10101011100011000000000110
+Resource=10101011100011000000000111
+Review=10101011100011000000001000
+Richard=10101011100011000000001001
+School=10101011100011000000001010
+Series=10101011100011000000001011
+Service=10101011100011000000001100
+Show=10101011100011000000001101
+Smith=10101011100011000000001110
+South=10101011100011000000001111
+Sport=10101011100011000000010000
+Star=10101011100011000000010001
+Street=10101011100011000000010010
+TV=10101011100011000000010011
+Teaching=10101011100011000000010100
+The=10101011100011000000010101
+Today=10101011100011000000010110
+Tonight=10101011100011000000010111
+Weather=10101011100011000000011000
+Western=10101011100011000000011001
+Westminster=10101011100011000000011010
+William=10101011100011000000011011
+With=10101011100011000000011100
+World=10101011100011000000011101
+about=10101011100011000000011110
+action-packed=10101011100011000000011111
+adventure=10101011100011000000100000
+afternoon=10101011100011000000100001
+alert=10101011100011000000100010
+all-star cast=10101011100011000000100011
+and=10101011100011000000100100
+anywhere=10101011100011000000100101
+audience=10101011100011000000100110
+based=10101011100011000000100111
+book=10101011100011000000101000
+business=10101011100011000000101001
+but=10101011100011000000101010
+celebrity=10101011100011000000101011
+chance=10101011100011000000101100
+chat=10101011100011000000101101
+child=10101011100011000000101110
+classic=10101011100011000000101111
+consumer=10101011100011000000110000
+contestants=10101011100011000000110001
+continues=10101011100011000000110010
+controversial=10101011100011000000110011
+dealer=10101011100011000000110100
+deliver=10101011100011000000110101
+discuss=10101011100011000000110110
+document=10101011100011000000110111
+drama=10101011100011000000111000
+edition=10101011100011000000111001
+education=10101011100011000000111010
+events=10101011100011000000111011
+every=10101011100011000000111100
+excellent=10101011100011000000111101
+eyed=10101011100011000000111110
+family=10101011100011000000111111
+famous=10101011100011000001000000
+featur=10101011100011000001000001
+film=10101011100011000001000010
+football=10101011100011000001000011
+for=10101011100011000001000100
+from=10101011100011000001000101
+general knowledge=10101011100011000001000110
+get=10101011100011000001000111
+guest=10101011100011000001001000
+guests=10101011100011000001001001
+has=10101011100011000001001010
+have=10101011100011000001001011
+headline=10101011100011000001001100
+her=10101011100011000001001101
+his=10101011100011000001001110
+home and abroad=10101011100011000001001111
+host=10101011100011000001010000
+how=10101011100011000001010001
+in=10101011100011000001010010
+including=10101011100011000001010011
+international=10101011100011000001010100
+interview=10101011100011000001010101
+introduce=10101011100011000001010110
+investigat=10101011100011000001010111
+invites=10101011100011000001011000
+issue=10101011100011000001011001
+knowledge=10101011100011000001011010
+life=10101011100011000001011011
+live=10101011100011000001011100
+look=10101011100011000001011101
+magazine=10101011100011000001011110
+meets =10101011100011000001011111
+morning=10101011100011000001100000
+morning magazine=10101011100011000001100001
+music=10101011100011000001100010
+near=10101011100011000001100011
+network=10101011100011000001100100
+new=10101011100011000001100101
+new series=10101011100011000001100110
+night=10101011100011000001100111
+of=10101011100011000001101000
+on=10101011100011000001101001
+onight=10101011100011000001101010
+out=10101011100011000001101011
+over=10101011100011000001101100
+part=10101011100011000001101101
+people=10101011100011000001101110
+phone=10101011100011000001101111
+poli=10101011100011000001110000
+police=10101011100011000001110001
+political chat show=10101011100011000001110010
+popular=10101011100011000001110011
+presented by =10101011100011000001110100
+programm=10101011100011000001110101
+quiz=10101011100011000001110110
+reconstruction=10101011100011000001110111
+report=10101011100011000001111000
+review=10101011100011000001111001
+school=10101011100011000001111010
+series=10101011100011000001111011
+short =10101011100011000001111100
+show=10101011100011000001111101
+some=10101011100011000001111110
+starring=10101011100011000001111111
+stars=10101011100011000010000000
+stories=10101011100011000010000001
+story=10101011100011000010000010
+studio=10101011100011000010000011
+surprise=10101011100011000010000100
+teller=10101011100011000010000101
+that=10101011100011000010000110
+the=10101011100011000010000111
+their=10101011100011000010001000
+them=10101011100011000010001001
+they=10101011100011000010001010
+this=10101011100011000010001011
+through=10101011100011000010001100
+to=10101011100011000010001101
+top=10101011100011000010001110
+trans=10101011100011000010001111
+under=10101011100011000010010000
+up=10101011100011000010010001
+very=10101011100011000010010010
+video=10101011100011000010010011
+view=10101011100011000010010100
+vintage=10101011100011000010010101
+visit=10101011100011000010010110
+was=10101011100011000010010111
+way=10101011100011000010011000
+week=10101011100011000010011001
+well=10101011100011000010011010
+what=10101011100011000010011011
+when=10101011100011000010011100
+which=10101011100011000010011101
+while=10101011100011000010011110
+who=10101011100011000010011111
+will=10101011100011000010100000
+win=10101011100011000010100001
+with=10101011100011000010100010
+words=10101011100011000010100011
+world=10101011100011000010100100
+written=10101011100011000010100101
+year=100010001100
+you=10110011010
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_bulsatcom_xepgdb.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_bulsatcom_xepgdb.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_bulsatcom_xepgdb.conf	(revision 6505)
@@ -0,0 +1,4 @@
+description=Krkadoni Bulsatcom Provider
+protocol=xepgdb
+headers_url=http://krkadoni.com/bulsat.headers.db.gz
+descriptors_url=http://krkadoni.com/bulsat.descriptors.db.gz
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_csat_xepgdb.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_csat_xepgdb.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_csat_xepgdb.conf	(revision 6505)
@@ -0,0 +1,4 @@
+description=Krkadoni CSAT Provider
+protocol=xepgdb
+headers_url=http://krkadoni.com/csat.headers.db.gz
+descriptors_url=http://krkadoni.com/csat.descriptors.db.gz
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_dplus_xepgdb.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_dplus_xepgdb.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_dplus_xepgdb.conf	(revision 6505)
@@ -0,0 +1,4 @@
+description=Krkadoni D+ Provider
+protocol=xepgdb
+headers_url=http://krkadoni.com/dplus.headers.db.gz
+descriptors_url=http://krkadoni.com/dplus.descriptors.db.gz
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_exyu_xepgdb.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_exyu_xepgdb.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_exyu_xepgdb.conf	(revision 6505)
@@ -0,0 +1,4 @@
+description=Krkadoni Ex-Yu Provider
+protocol=xepgdb
+headers_url=http://krkadoni.com/crossepg.headers.db.gz
+descriptors_url=http://krkadoni.com/crossepg.descriptors.db.gz
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_exyu_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_exyu_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_exyu_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Krkadoni ExYu XMLTV
+protocol=xmltv
+channels=http://www.krkadoni.com/krkadoni.channels.xml.gz
+url=http://krkadoni.com/krkadonixmltv_exyu.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_meo_zon_xepgdb.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_meo_zon_xepgdb.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_meo_zon_xepgdb.conf	(revision 6505)
@@ -0,0 +1,4 @@
+description=Krkadoni MEO/ZON Provider
+protocol=xepgdb
+headers_url=http://krkadoni.com/meozon.headers.db.gz
+descriptors_url=http://krkadoni.com/meozon.descriptors.db.gz
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_multichoice_xepgdb.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_multichoice_xepgdb.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_multichoice_xepgdb.conf	(revision 6505)
@@ -0,0 +1,4 @@
+description=Krkadoni ZA Multichoice/DSTV/OSN Provider
+protocol=xepgdb
+headers_url=http://krkadoni.com/multichoice.headers.db.gz
+descriptors_url=http://krkadoni.com/multichoice.descriptors.db.gz
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_nl_be_xepgdb.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_nl_be_xepgdb.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_nl_be_xepgdb.conf	(revision 6505)
@@ -0,0 +1,4 @@
+description=Krkadoni NL/BE Provider
+protocol=xepgdb
+headers_url=http://krkadoni.com/nlbe.headers.db.gz
+descriptors_url=http://krkadoni.com/nlbe.descriptors.db.gz
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_nordic_xepgdb.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_nordic_xepgdb.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_nordic_xepgdb.conf	(revision 6505)
@@ -0,0 +1,4 @@
+description=Krkadoni Nordic Provider
+protocol=xepgdb
+headers_url=http://krkadoni.com/nordic.headers.db.gz
+descriptors_url=http://krkadoni.com/nordic.descriptors.db.gz
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_nova_xepgdb.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_nova_xepgdb.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_nova_xepgdb.conf	(revision 6505)
@@ -0,0 +1,4 @@
+description=Krkadoni Nova Provider
+protocol=xepgdb
+headers_url=http://krkadoni.com/nova.headers.db.gz
+descriptors_url=http://krkadoni.com/nova.descriptors.db.gz
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_osn_xepgdb.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_osn_xepgdb.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_osn_xepgdb.conf	(revision 6505)
@@ -0,0 +1,4 @@
+description=Krkadoni OSN Provider
+protocol=xepgdb
+headers_url=http://krkadoni.com/osn.headers.db.gz
+descriptors_url=http://krkadoni.com/osn.descriptors.db.gz
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_poland_xepgdb.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_poland_xepgdb.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_poland_xepgdb.conf	(revision 6505)
@@ -0,0 +1,4 @@
+description=Krkadoni Poland Provider
+protocol=xepgdb
+headers_url=http://krkadoni.com/poland.headers.db.gz
+descriptors_url=http://krkadoni.com/poland.descriptors.db.gz
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_skyde_xepgdb.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_skyde_xepgdb.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_skyde_xepgdb.conf	(revision 6505)
@@ -0,0 +1,4 @@
+description=Krkadoni Sky DE Provider
+protocol=xepgdb
+headers_url=http://krkadoni.com/skyde.headers.db.gz
+descriptors_url=http://krkadoni.com/skyde.descriptors.db.gz
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_skyit_xepgdb.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_skyit_xepgdb.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_skyit_xepgdb.conf	(revision 6505)
@@ -0,0 +1,4 @@
+description=Krkadoni Sky IT Provider
+protocol=xepgdb
+headers_url=http://krkadoni.com/skyit.headers.db.gz
+descriptors_url=http://krkadoni.com/skyit.descriptors.db.gz
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_skylink_xepgdb.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_skylink_xepgdb.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_skylink_xepgdb.conf	(revision 6505)
@@ -0,0 +1,4 @@
+description=Krkadoni Skylink CZ/SK Provider
+protocol=xepgdb
+headers_url=http://krkadoni.com/skylink.headers.db.gz
+descriptors_url=http://krkadoni.com/skylink.descriptors.db.gz
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_skyuk_xepgdb.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_skyuk_xepgdb.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_skyuk_xepgdb.conf	(revision 6505)
@@ -0,0 +1,4 @@
+description=Krkadoni Sky UK Provider
+protocol=xepgdb
+headers_url=http://krkadoni.com/skyuk.headers.db.gz
+descriptors_url=http://krkadoni.com/skyuk.descriptors.db.gz
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_upc_xepgdb.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_upc_xepgdb.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/krkadoni_upc_xepgdb.conf	(revision 6505)
@@ -0,0 +1,4 @@
+description=Krkadoni UPC Direct Provider
+protocol=xepgdb
+headers_url=http://krkadoni.com/upc.headers.db.gz
+descriptors_url=http://krkadoni.com/upc.descriptors.db.gz
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/linuxsat_exussr_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/linuxsat_exussr_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/linuxsat_exussr_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Linuxsat ExUSSR XMLTV
+protocol=xmltv
+channels=http://linux-sat.tv/epg/ls.channels.xml.gz
+url=http://linux-sat.tv/epg/tvprogram_ua_ru.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/mediaprem_script.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/mediaprem_script.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/mediaprem_script.conf	(revision 6505)
@@ -0,0 +1,3 @@
+protocol=script
+filename=mediaprem/mediaprem.py
+description=MEDIAPREM: download EPG from Mediaset website
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rai_script.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rai_script.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rai_script.conf	(revision 6505)
@@ -0,0 +1,3 @@
+protocol=script
+filename=rai/rai.py
+description=RAI: download EPG from RAI website
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_benelux_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_benelux_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_benelux_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Benelux XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvbenl.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_bulgaria_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_bulgaria_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_bulgaria_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Bulgaria XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvbulsat.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_denmark_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_denmark_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_denmark_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Denmark XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels-denmark.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvnordic.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_erotic_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_erotic_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_erotic_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Erotic XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltverotic.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_finland_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_finland_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_finland_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Finland XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels-finland.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvnordic.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_france_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_france_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_france_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec France XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvcsat.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_germany_austria_swiss_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_germany_austria_swiss_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_germany_austria_swiss_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Germany/Austria/Swiss XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvskyde.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_greece_english_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_greece_english_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_greece_english_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Greece in English XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels-greece-en.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvnova.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_greece_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_greece_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_greece_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Greece XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvnova.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_hungary_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_hungary_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_hungary_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Hungary XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvmagyar.gz
+preferred_language=dut
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_italy_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_italy_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_italy_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Italy XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvskyit.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_norway_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_norway_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_norway_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Norway XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels-norway.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvnordic.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_osn_jsc_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_osn_jsc_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_osn_jsc_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec OSN/JSC XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvosn.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_poland_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_poland_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_poland_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Poland XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvpoland.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_portugal_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_portugal_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_portugal_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Portugal XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvportugal.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_romania_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_romania_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_romania_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Romania XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvromania.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_serbia_croatia_montenegro_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_serbia_croatia_montenegro_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_serbia_croatia_montenegro_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Serbia/Croatia/Montenegro XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvexyu.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_slovack_czech_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_slovack_czech_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_slovack_czech_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Slovak/Czech XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvskylink.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_slovenia_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_slovenia_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_slovenia_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Slovenia XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels-slovenia.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvexyu.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_spain_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_spain_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_spain_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Spain XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvdplus.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_sweden_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_sweden_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_sweden_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec Sweden XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels-sweden.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvnordic.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_uk_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_uk_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_uk_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec UK XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvuk.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_upc_direct_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_upc_direct_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_upc_direct_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec UK BBCi XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.oostwestedpnet.be/Box/rytecxmltvbbci.xml
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_west_africa_csat_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_west_africa_csat_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_west_africa_csat_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec West-Africa / Csat Horizons XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://www.xmltvepg.be/rytecxmltvcsathorizons.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_za_multichoice_dstv_osn_xmltv.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_za_multichoice_dstv_osn_xmltv.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/rytec_za_multichoice_dstv_osn_xmltv.conf	(revision 6505)
@@ -0,0 +1,5 @@
+description=Rytec ZA Multichoice/DSTV/OSN XMLTV
+protocol=xmltv
+channels=http://www.xmltvepg.be/rytec.channels.xml.gz
+url=http://zaxmltv.flash.za.org/schedule/ZA-XMLTV.xml.gz
+preferred_language=eng
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyit_hotbird_13.0.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyit_hotbird_13.0.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyit_hotbird_13.0.conf	(revision 6505)
@@ -0,0 +1,13 @@
+description=Sky Italia OpenTV (Hotbird on 13.0)
+# nid ,tsid, sid
+nid=64511
+tsid=5800
+sid=3635
+namespace=8519680
+# channels pids
+channels_pids=17
+# titles pids
+titles_pids=48|49|50|51|52|53|54|55
+# summaries pids
+summaries_pids=64|65|66|67|68|69|70|71
+protocol=opentv
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyit_hotbird_13.0.dict
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyit_hotbird_13.0.dict	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyit_hotbird_13.0.dict	(revision 6505)
@@ -0,0 +1,510 @@
+ =00001011010110001111010101010
+ =00001011010110001111010101011
+ =00001011010110001111010101100
+ =00001011010110001111010101101
+ =00001011010110001111010101110
+ =00001011010110001111010101111
+ =00001011010110001111010110000
+ =00001011010110001111010110001
+ =00001011010110001111010110010
+ =00001011010110001111010110011
+ =00001011010110001111010110100
+ =00001011010110001111010110101
+ =00001011010110001111010110110
+ =1001110
+ =00001011010110001111010110111
+ =00001011010110001111010111000
+ =00001011010110001111010111001
+ =00001011010110001111010111010
+ =00001011010110001111010111011
+ =00001011010110001111010111100
+ =00001011010110001111010111101
+ =00001011010110001111010111110
+ =00001011010110001111010111111
+ =00001011010110001111011000000
+ =00001011010110001111011000001
+ =00001011010110001111011000010
+ =00001011010110001111011000011
+ =00001011010110001111011000100
+ =00001011010110001111011000101
+ =00001011010110001111011000110
+ =00001011010110001111011000111
+ =00001011010110001111011001000
+ =01
+!=1110000011101
+"=11100010000100011
+#=00001011010110001111011001001
+$=00001011010110001111011001010
+%=00001011010110001111011001011
+&=11100010000101
+'=0000100
+(=0000101101010
+)=110100111111
+*=00001011010110001111011001100
++=000010110101100011111
+,=110000
+-=10110011
+.=100110
+/=111000100001001
+0=10010011
+1=100100000
+2=1111011001
+3=1110001110
+4=11000100101
+5=111101110100
+6=101100101111
+7=110100011110
+8=11010001110
+9=1111010111
+:=100100011
+;=10000111101
+<=00001011010110001111011001101
+==00001011010110001111011001110
+>=00001011010110001111011001111
+?=1100110110110
+@=1110001000010000
+A=00001010
+B=111101001
+C=10010100
+D=100001010
+E=111000000
+F=1110001100
+G=100101100
+H=1000011111
+I=1111011111
+J=1100010110
+K=11110100011
+L=001111101
+M=100001101
+N=100001011
+O=1100101011
+P=110100000
+Q=00001011000
+R=110010100
+S=10110100
+T=110101100
+U=110100010011
+V=1001000011
+W=1101000110
+X=1110001011001
+Y=1100011110011
+Z=1100010100110
+[=00001011010110001111011010000
+\=00001011010110001111011010001
+]=00001011010110001111011010010
+^=0000101101011000100
+_=00001011010110001111011010011
+`=00001011010111
+a=11111
+b=11100001
+c=111001
+d=1011000
+e=1010
+f=0011011
+g=000011
+h=10110110
+i=0001
+j=110100010000
+k=110001100
+l=1111001
+m=100010
+n=10111
+o=0010
+p=100011
+q=1110001001
+r=11011
+s=00000
+t=11101
+u=001110
+v=1100111
+w=001100110
+x=11100011110
+y=111101101
+z=0011010
+{=00001011010110001111011010100
+|=00001011010110001111011010101
+}=00001011010110001111011010110
+~=00001011010110001111011010111
+ =00001011010110001111011011000
+ =000010110101100000
+ =00001011010110001111011011001
+ =00001011010110001111011011010
+ =00001011010110001111011011011
+ =00001011010110001111011011100
+ =00001011010110001111011011101
+ =00001011010110001111011011110
+ =00001011010110001111011011111
+ =11100010000100010
+ =000010110101100001
+ =00001011010110001111011100000
+ =00001011010110001111011100001
+ =00001011010110001111011100010
+ =00001011010110001111011100011
+ =00001011010110001111011100100
+ =00001011010110001111011100101
+ =00001011010110001111011100110
+ =00001011010110001111011100111
+ =00001011010110001110
+ =00001011010110001111011101000
+ =00001011010110001111011101001
+ =00001011010110001111011101010
+ =00001011010110001111011101011
+ =0000101101011000101
+ =00001011010110001111011101100
+ =00001011010110001111011101101
+ =00001011010110001111011101110
+ =00001011010110001111011101111
+ =00001011010110001111011110000
+ =00001011010110001111011110001
+ =00001011010110001111011110010
+ =00001011010110001111011110011
+ =00001011010110001111011110100
+¡=00001011010110001111011110101
+¢=00001011010110001111011110110
+£=00001011010110001111011110111
+¤=00001011010110001111011111000
+¥=00001011010110001111011111001
+¦=00001011010110001111011111010
+§=00001011010110001111011111011
+¨=00001011010110001111011111100
+©=00001011010110001111011111101
+ª=00001011010110001111011111110
+«=00001011010110001111011111111
+¬=0000101101011000111100000000
+­=0000101101011000111100000001
+®=0000101101011000111100000010
+¯=0000101101011000111100000011
+°=0000101101011000111100000100
+±=0000101101011000111100000101
+²=0000101101011000111100000110
+³=0000101101011000111100000111
+´=0000101101011000111100001000
+µ=0000101101011000111100001001
+¶=0000101101011000111100001010
+·=0000101101011001
+¸=0000101101011000111100001011
+¹=0000101101011000111100001100
+º=0000101101011000111100001101
+»=0000101101011000111100001110
+¼=0000101101011000111100001111
+½=0000101101011000111100010000
+¾=0000101101011000111100010001
+¿=0000101101011000111100010010
+À=0000101101011000111100010011
+Á=0000101101011000111100010100
+Â=0000101101011000111100010101
+Ã=0000101101011000111100010110
+Ä=0000101101011000111100010111
+Å=0000101101011000111100011000
+Æ=000010110101101
+Ç=0000101101011000111100011001
+È=0000101101011000111100011010
+É=0000101101011000111100011011
+Ê=0000101101011000111100011100
+Ë=0000101101011000111100011101
+Ì=0000101101011000111100011110
+Í=0000101101011000111100011111
+Î=0000101101011000111100100000
+Ï=0000101101011000111100100001
+Ð=0000101101011000111100100010
+Ñ=0000101101011000111100100011
+Ò=0000101101011000111100100100
+Ó=0000101101011000111100100101
+Ô=0000101101011000111100100110
+Õ=0000101101011000111100100111
+Ö=0000101101011000111100101000
+×=0000101101011000111100101001
+Ø=0000101101011000111100101010
+Ù=0000101101011000111100101011
+Ú=0000101101011000111100101100
+Û=0000101101011000111100101101
+Ü=0000101101011000111100101110
+Ý=0000101101011000111100101111
+Þ=0000101101011000111100110000
+ß=0000101101011000111100110001
+à=0000101101011000110
+á=0000101101011000111100110010
+â=0000101101011000111100110011
+ã=0000101101011000111100110100
+ä=0000101101011000111100110101
+å=0000101101011000111100110110
+æ=0000101101011000111100110111
+ç=0000101101011000111100111000
+è=0000101101011000111100111001
+é=0000101101011000111100111010
+ê=0000101101011000111100111011
+ë=0000101101011000111100111100
+ì=0000101101011000111100111101
+í=0000101101011000111100111110
+î=0000101101011000111100111111
+ï=0000101101011000111101000000
+ð=0000101101011000111101000001
+ñ=0000101101011000111101000010
+ò=0000101101011000111101000011
+ó=0000101101011000111101000100
+ô=0000101101011000111101000101
+õ=0000101101011000111101000110
+ö=0000101101011000111101000111
+÷=0000101101011000111101001000
+ø=0000101101011000111101001001
+ù=0000101101011000111101001010
+ú=0000101101011000111101001011
+û=0000101101011000111101001100
+ü=0000101101011000111101001101
+ý=0000101101011000111101001110
+þ=0000101101011000111101001111
+ÿ=0000101101011000111101010000
+(dur=100001111000
+2001=001111100
+2002=111000110101
+Adulti=100001111001
+Alle=1100110111
+American=10110101100
+Argentina=110010101011
+Attualita'=110001000001
+Bateman=10010111111
+Bechis=1100010111011
+Campionato=1101001111000
+Carlos=1101000011101
+Cartoon=11110111011
+Club=10000110010
+Commedia=100001100001
+Con=10110101101
+D'Alo'=1100100011111
+Da=1001010111
+Dal=1111010100011
+Dalle=10010111110
+Drammatico=111101111001
+Durante=1101000111110
+Echeverria=1100011100110
+Emmanuelle=1100011100111
+Enzo=1101000100010
+Fares=00001011011
+Figli=1100100011000
+Film=1101011010
+Fine=100001001100
+Fiumi=00001011100
+Francia=10000110001
+Giallo=110001001000
+Giovanni=1100011101000
+Harron=10011110000
+ITV=1101000100100
+Il=0011001110
+In=1001011011
+Informazione=11110100001
+Intrattenimento=1000010000
+Italia=11100010001
+Javier=1100011101001
+Jean=10010101011
+John=1111011100101
+Kassovitz=00110000101
+L'appassionante=00001011101
+La=1001010110
+Le=11000100111
+Ma=1101001110
+Magazine=100001110010
+Mammuccari=1100011101010
+Manhattan=10110010010
+Marco=1110001011110
+Mary=10011110110
+Mathieu=00110000110
+Michael=1101001111011
+Momo=110010001011
+Nadia=00001011110
+News=110100111110
+Notiziario=101100101110
+Orario=1001000100
+Patrick=10110010110
+Paul=000010110011
+Per=11000100110
+Peter=1100101010101
+Programmazione=1110001101001
+Psycho=10011110111
+Regia=110010000
+Reno=00110000111
+Rosa=1100011110101
+Rubrica=1111011100100
+Sandrelli=1100100010001
+Seigner=1100011101011
+Servizi=001100000110
+Snow=100100001000
+Sorvino=1100011110110
+Stefania=1101011011010
+Stream=111101000100
+Street=10110101111
+Streghe=1100011101100
+TRAMA:=1100010111010
+Teo=110001110010
+USA=1101000101
+Un=11110111101
+Una=101100100010
+Veronesi=1100011101101
+Vincent=00110001001
+Wall=11000100001
+World=001100010110
+XXX=10000110011
+ad=1111010110
+affidare=00110000100
+ai=1001011110
+al=0011110
+alla=11010110111
+alle=111101110101
+amici=111000101110
+ammazzare=10011110001
+and=1111010101
+anfiteatro=1100100011001
+anni=10010101010
+as=110011010
+attraverso=1101011011001
+aver=000010110100
+bambina=1101000100011
+banda=1110001011000
+bello=10110101000
+brani=1100100010010
+broker=10011110010
+business=000010110010
+casa=101100100011
+casi=10000111010
+cassel=00001011111
+cerca=11100010100
+che=10010010
+chilometri=00110001111
+citta'=110001000101
+come=110001011100
+compagnia=1100110110001
+con=11010010
+conquista=1101000111111
+contro=110001000100
+crede=1110001111110
+cui=001100111110
+cultura=100001110001
+curiosita'=001100010111
+da=00110010
+dai=1101000100101
+dal=11110110000
+dalla=100101101001
+decidG266  :  dedicato=0000101101011000111101010001
+degli=110001000000
+dei=0011000110
+del=111100010
+della=1011001010
+delle=11000111000
+destra=1100101010001
+deve=1111010001011
+di=100000
+diabolici=1100100011010
+dice=1100110110000
+diretta=100100001011
+distanza=00110000000
+divide=10110010011
+divisi=1100011101110
+dolce=1101001111001
+domani=1111010100010
+due=1100011111
+e'=110001101
+ed=101101111
+essere=1110001000000
+esseri=1110001111101
+eventiG=0000101101011000111101010010
+fatti=001100111111
+feste=10110101001
+film=10000100011
+gemelli=1110001000011
+giorno=11110100000
+giovane=11100000110
+giovani=1111011110001
+gli=100101110
+grande=1110001011111
+grandi=1111010001010
+grigi'=1100100011011
+ha=1100010101
+il=11001011
+imbattere=1100100011100
+in=1101010
+incinta=1100101010000
+informazione=110001001001
+inizio=1001010100
+internazionale=100001110111
+interviste=100100001001
+la=11001100
+lavoro=11010000110
+le=11010111
+levatrice=1100011101111
+libro=1100011110100
+lo=111100011
+loro=11000101000
+ma=10011111
+maggiori=100001110110
+malcapitati=10110010000
+maschietto=1100011110000
+mondo=11100010101
+musica=111000001111
+nato=111101110011
+nel=11110111000
+nella=1111010100000
+nello=10000100100
+news=10010110101
+non=00110011110
+nord=1100100011101
+nuovi=001100000111
+of=1011010101
+ogni=100001110011
+ore=1101000010
+parte=1101011011011
+per=00111111
+piccola=1101001111010
+piu'=1001111010
+poliziotti=00110001110
+porpora=00110000001
+prima=1110001111100
+produttore=1100011110111
+programmazione=1110001101000
+proprio=1101011011000
+prossimo=1001000101
+quattro=1111011000110
+regime=1100011110001
+ricco=10110101110
+ricordi=1100101010100
+rovine=1110001000001
+salvare=1110000011100
+scrittore=1100110110111
+scrive=1101000011110
+serie=1111011000111
+servizi=100001110000
+settimanale=1100010100111
+si=11110000
+singolari=00110001000
+solo=110010001010
+sono=11000100011
+stesso=10000100010
+storia=11100011011
+streghe=1100100010000
+su=1110000010
+sua=10000100101
+successo=100101101000
+sui=110011011001
+sulle=100100001010
+suo=10000100111
+suoi=1101000011100
+tale=110010101001
+tempo=111101100010
+the=11110101001
+timida=1100100011110
+torturare=10011110011
+tra=110100110
+trasformarlo=1100011110010
+trecento=00110000010
+trovato=1101000011111
+tutto=110011011010
+ultimi=1100100010011
+un=11001001
+una=101101110
+uno=111000101101
+uomini=1111011110000
+vedono=00110001010
+vengono=100001001101
+verso=100001100000
+viaggio=110001010010
+viene=1111010100001
+vita=11000101111
+vuole=1110001111111
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyuk_astra2_28.2.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyuk_astra2_28.2.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyuk_astra2_28.2.conf	(revision 6505)
@@ -0,0 +1,13 @@
+description=Sky Uk OpenTV (Astra2 on 28.2)
+# nid ,tsid, sid
+nid=2
+tsid=2004
+sid=4152
+namespace=18481152
+# channels pids
+channels_pids=17
+# titles pids
+titles_pids=48|49|50|51|52|53|54|55
+# summaries pids
+summaries_pids=64|65|66|67|68|69|70|71
+protocol=opentv
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyuk_astra2_28.2.dict
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyuk_astra2_28.2.dict	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyuk_astra2_28.2.dict	(revision 6505)
@@ -0,0 +1,512 @@
+ =101010111000110000101001100
+ =101010111000110000101001101
+ =101010111000110000101001110
+ =101010111000110000101001111
+ =101010111000110000101010000
+ =101010111000110000101010001
+ =101010111000110000101010010
+ =101010111000110000101010011
+ =101010111000110000101010100
+=0001000
+ =1110111
+ =101010111000110000101010101
+ =101010111000110000101010110
+ =101010111000110000101010111
+ =101010111000110000101011000
+ =101010111000110000101011001
+ =101010111000110000101011010
+ =101010111000110000101011011
+ =101010111000110000101011100
+ =101010111000110000101011101
+ =101010111000110000101011110
+ =101010111000110000101011111
+ =101010111000110000101100000
+ =101010111000110000101100001
+ =101010111000110000101100010
+ =101010111000110000101100011
+ =101010111000110000101100100
+ =101010111000110000101100101
+ =101010111000110000101100110
+ =101010111000110000101100111
+ =101010111000110000101101000
+ =101010111000110000101101001
+ =110
+!=01000011000
+"=101010111000110000101101010
+#=101010111000110000101101011
+$=1010101110001101
+%=101010111000110000101101100
+&=10000011101
+'=10000010
+(=11101000101
+)=1010101100
+*=100010101110
++=101010111000110000101101101
+,=1011000
+-=10001011
+.=1110110
+/=00010100011110
+0=111010010
+1=101100111
+2=1000101000
+3=1000001111
+4=0001010000
+5=1110101000
+6=1000101001
+7=1000100010
+8=10001010110
+9=0100001101
+:=11101000110
+;=00010100010
+<=1110100011111
+==101010111000110000101101110
+>=1110101001100
+?=111010100111
+@=101010111000110001
+A=11100010
+B=01000000
+C=01000010
+D=111000111
+E=1110100000
+F=101010100
+G=100010000
+H=101010101
+I=1110100001
+J=000101001
+K=1110100111
+L=100000110
+M=10001001
+N=111010111
+O=010000010
+P=00010101
+Q=1000101010111
+R=111010110
+S=0001001
+T=0001011
+U=10101011101
+V=11101010101
+W=10110010
+X=1110001101101111
+Y=10101011110
+Z=1110101010000
+[=10101011100011001
+\=101010111000110000101101111
+]=11100011011011100
+^=101010111000110000101110000
+_=101010111000110000101110001
+`=11101010010
+a=1001
+b=1110000
+c=111001
+d=01001
+e=1111
+f=100001
+g=100011
+h=10111
+i=0101
+j=11100011010
+k=1000000
+l=10100
+m=101011
+n=0111
+o=0011
+p=000111
+q=10101011011
+r=0010
+s=0000
+t=0110
+u=101101
+v=1010100
+w=000110
+x=1110101011
+y=010001
+z=1011001100
+{=101010111000110000101110010
+|=101010111000110000101110011
+}=101010111000110000101110100
+~=101010111000110000101110101
+ =101010111000110000101110110
+ =101010111000110000101110111
+ =101010111000110000101111000
+ =101010111000110000101111001
+ =101010111000110000101111010
+ =101010111000110000101111011
+ =101010111000110000101111100
+ =101010111000110000101111101
+ =101010111000110000101111110
+ =101010111000110000101111111
+ =101010111000110000110000000
+ =101010111000110000110000001
+ =101010111000110000110000010
+ =101010111000110000110000011
+ =101010111000110000110000100
+ =101010111000110000110000101
+ =101010111000110000110000110
+ =101010111000110000110000111
+ =101010111000110000110001000
+ =101010111000110000110001001
+ =101010111000110000110001010
+ =101010111000110000110001011
+ =101010111000110000110001100
+ =101010111000110000110001101
+ =101010111000110000110001110
+ =101010111000110000110001111
+ =101010111000110000110010000
+ =101010111000110000110010001
+ =101010111000110000110010010
+ =11100011011011101
+ =101010111000110000110010011
+ =101010111000110000110010100
+ =101010111000110000110010101
+ =101010111000110000110010110
+¡=101010111000110000110010111
+¢=101010111000110000110011000
+£=101010111000110000110011001
+¤=101010111000110000110011010
+¥=101010111000110000110011011
+¦=101010111000110000110011100
+§=101010111000110000110011101
+¨=101010111000110000110011110
+©=101010111000110000110011111
+ª=101010111000110000110100000
+«=101010111000110000110100001
+¬=101010111000110000110100010
+­=101010111000110000110100011
+®=101010111000110000110100100
+¯=101010111000110000110100101
+°=101010111000110000110100110
+±=101010111000110000110100111
+²=101010111000110000110101000
+³=101010111000110000110101001
+´=101010111000110000110101010
+µ=101010111000110000110101011
+¶=101010111000110000110101100
+·=101010111000110000110101101
+¸=101010111000110000110101110
+¹=101010111000110000110101111
+º=101010111000110000110110000
+»=101010111000110000110110001
+¼=101010111000110000110110010
+½=101010111000110000110110011
+¾=101010111000110000110110100
+¿=101010111000110000110110101
+À=101010111000110000110110110
+Á=101010111000110000110110111
+Â=101010111000110000110111000
+Ã=101010111000110000110111001
+Ä=101010111000110000110111010
+Å=101010111000110000110111011
+Æ=101010111000110000110111100
+Ç=101010111000110000110111101
+È=101010111000110000110111110
+É=101010111000110000110111111
+Ê=101010111000110000111000000
+Ë=101010111000110000111000001
+Ì=101010111000110000111000010
+Í=101010111000110000111000011
+Î=101010111000110000111000100
+Ï=101010111000110000111000101
+Ð=101010111000110000111000110
+Ñ=101010111000110000111000111
+Ò=101010111000110000111001000
+Ó=101010111000110000111001001
+Ô=101010111000110000111001010
+Õ=101010111000110000111001011
+Ö=101010111000110000111001100
+×=101010111000110000111001101
+Ø=101010111000110000111001110
+Ù=101010111000110000111001111
+Ú=101010111000110000111010000
+Û=101010111000110000111010001
+Ü=101010111000110000111010010
+Ý=101010111000110000111010011
+Þ=101010111000110000111010100
+ß=101010111000110000111010101
+à=101010111000110000111010110
+á=101010111000110000111010111
+â=101010111000110000111011000
+ã=101010111000110000111011001
+ä=101010111000110000111011010
+å=101010111000110000111011011
+æ=101010111000110000111011100
+ç=101010111000110000111011101
+è=101010111000110000111011110
+é=101010111000110000111011111
+ê=101010111000110000111100000
+ë=101010111000110000111100001
+ì=101010111000110000111100010
+í=101010111000110000111100011
+î=101010111000110000111100100
+ï=101010111000110000111100101
+ð=101010111000110000111100110
+ñ=101010111000110000111100111
+ò=101010111000110000111101000
+ó=101010111000110000111101001
+ô=101010111000110000111101010
+õ=101010111000110000111101011
+ö=101010111000110000111101100
+÷=101010111000110000111101101
+ø=101010111000110000111101110
+ù=101010111000110000111101111
+ú=101010111000110000111110000
+û=101010111000110000111110001
+ü=101010111000110000111110010
+ý=101010111000110000111110011
+þ=101010111000110000111110100
+ÿ=101010111000110000111110101
+(Including =10101011111110
+(New Series)=11101000100010
+(Part =1110100011101
+(Repeat)=1110100110
+(Stereo)=010000111
+(Stereo) (Teletext)=010000011
+(Teletext)=1110001100
+(Widescreen)=100000111001110
+Action=101010111000111
+Adventures=10110011011111
+America=0100001100100
+Animated=111010100110111
+Australia=0100001100101
+Away=11101010100010
+BBC=10101011111111
+Baby=11100011011000
+Best=11101010100011
+Big=10110011011000
+Bill=1000101011111
+Black=1000101010000
+Blue=1011001101110
+Breakfast=000101000110
+Britain=1010101111100
+British=1110100011100
+Business=0100001100110
+Call=1010101111101
+Cartoon=10101011100000
+Channel=10101011100001
+Children=11101010100111
+Clock=11100011011001
+Comedy=11101000100011
+Cook=111010101001010
+Country=111010100110110
+Directed by =101010110100
+Drama=0100001100111
+East=1000101010001
+Education=100000111001111
+English=00010100011111
+Europe=0001010001110
+Extra=10110011011001
+Final=10101011100010
+Financial=111000110110100
+For=111000110111
+French=11101000111101
+From=1000101010010
+George=1010101111110
+Get=1000100011010
+Girls=10001000110110
+Golden=10001000110111
+Golf=111010101001011
+Good=1010101101010
+Great=11101000100100
+Hampshire=111010101001100
+Headlines=1000101010011
+Hear=11101010011010
+Hill=1000001110000
+Hollywood=111000110110101
+Home=1000101010100
+Hour=11101000100101
+House=1000001110010
+How=1010101101011
+ITN=11101010100100
+Important=111010101001101
+Including=1000101011110
+International=11101000100110
+John=10001000111
+Last=11101000100111
+Late=10000011100110
+Learn=10001010101100
+Little=10001010101101
+Live=1110100010000
+London=11101000111100
+Look=10110011011110
+Lunch=111000110110110
+Man=1000101010101
+Mark=1000001110001
+Meridian=101010111001
+Michael=1011001101101
+Minutes=101010111000110000111110110
+More=101010111000110000111110111
+Morning=101010111000110000111111000
+Murder=101010111000110000111111001
+Nation=101010111000110000111111010
+Neighbours=101010111000110000111111011
+New=101010111000110000111111100
+News & Weather=101010111000110000111111101
+News And Weather=101010111000110000111111110
+Paul=101010111000110000111111111
+Plus=10101011100011000000000000
+Prayer=10101011100011000000000001
+Present=10101011100011000000000010
+Presented by=10101011100011000000000011
+Quiz=10101011100011000000000100
+Regional=10101011100011000000000101
+Represent=10101011100011000000000110
+Resource=10101011100011000000000111
+Review=10101011100011000000001000
+Richard=10101011100011000000001001
+School=10101011100011000000001010
+Series=10101011100011000000001011
+Service=10101011100011000000001100
+Show=10101011100011000000001101
+Smith=10101011100011000000001110
+South=10101011100011000000001111
+Sport=10101011100011000000010000
+Star=10101011100011000000010001
+Street=10101011100011000000010010
+TV=10101011100011000000010011
+Teaching=10101011100011000000010100
+The=10101011100011000000010101
+Today=10101011100011000000010110
+Tonight=10101011100011000000010111
+Weather=10101011100011000000011000
+Western=10101011100011000000011001
+Westminster=10101011100011000000011010
+William=10101011100011000000011011
+With=10101011100011000000011100
+World=10101011100011000000011101
+about=10101011100011000000011110
+action-packed=10101011100011000000011111
+adventure=10101011100011000000100000
+afternoon=10101011100011000000100001
+alert=10101011100011000000100010
+all-star cast=10101011100011000000100011
+and=10101011100011000000100100
+anywhere=10101011100011000000100101
+audience=10101011100011000000100110
+based=10101011100011000000100111
+book=10101011100011000000101000
+business=10101011100011000000101001
+but=10101011100011000000101010
+celebrity=10101011100011000000101011
+chance=10101011100011000000101100
+chat=10101011100011000000101101
+child=10101011100011000000101110
+classic=10101011100011000000101111
+consumer=10101011100011000000110000
+contestants=10101011100011000000110001
+continues=10101011100011000000110010
+controversial=10101011100011000000110011
+dealer=10101011100011000000110100
+deliver=10101011100011000000110101
+discuss=10101011100011000000110110
+document=10101011100011000000110111
+drama=10101011100011000000111000
+edition=10101011100011000000111001
+education=10101011100011000000111010
+events=10101011100011000000111011
+every=10101011100011000000111100
+excellent=10101011100011000000111101
+eyed=10101011100011000000111110
+family=10101011100011000000111111
+famous=10101011100011000001000000
+featur=10101011100011000001000001
+film=10101011100011000001000010
+football=10101011100011000001000011
+for=10101011100011000001000100
+from=10101011100011000001000101
+general knowledge=10101011100011000001000110
+get=10101011100011000001000111
+guest=10101011100011000001001000
+guests=10101011100011000001001001
+has=10101011100011000001001010
+have=10101011100011000001001011
+headline=10101011100011000001001100
+her=10101011100011000001001101
+his=10101011100011000001001110
+home and abroad=10101011100011000001001111
+host=10101011100011000001010000
+how=10101011100011000001010001
+in=10101011100011000001010010
+including=10101011100011000001010011
+international=10101011100011000001010100
+interview=10101011100011000001010101
+introduce=10101011100011000001010110
+investigat=10101011100011000001010111
+invites=10101011100011000001011000
+issue=10101011100011000001011001
+knowledge=10101011100011000001011010
+life=10101011100011000001011011
+live=10101011100011000001011100
+look=10101011100011000001011101
+magazine=10101011100011000001011110
+meets =10101011100011000001011111
+morning=10101011100011000001100000
+morning magazine=10101011100011000001100001
+music=10101011100011000001100010
+near=10101011100011000001100011
+network=10101011100011000001100100
+new=10101011100011000001100101
+new series=10101011100011000001100110
+night=10101011100011000001100111
+of=10101011100011000001101000
+on=10101011100011000001101001
+onight=10101011100011000001101010
+out=10101011100011000001101011
+over=10101011100011000001101100
+part=10101011100011000001101101
+people=10101011100011000001101110
+phone=10101011100011000001101111
+poli=10101011100011000001110000
+police=10101011100011000001110001
+political chat show=10101011100011000001110010
+popular=10101011100011000001110011
+presented by =10101011100011000001110100
+programm=10101011100011000001110101
+quiz=10101011100011000001110110
+reconstruction=10101011100011000001110111
+report=10101011100011000001111000
+review=10101011100011000001111001
+school=10101011100011000001111010
+series=10101011100011000001111011
+short =10101011100011000001111100
+show=10101011100011000001111101
+some=10101011100011000001111110
+starring=10101011100011000001111111
+stars=10101011100011000010000000
+stories=10101011100011000010000001
+story=10101011100011000010000010
+studio=10101011100011000010000011
+surprise=10101011100011000010000100
+teller=10101011100011000010000101
+that=10101011100011000010000110
+the=10101011100011000010000111
+their=10101011100011000010001000
+them=10101011100011000010001001
+they=10101011100011000010001010
+this=10101011100011000010001011
+through=10101011100011000010001100
+to=10101011100011000010001101
+top=10101011100011000010001110
+trans=10101011100011000010001111
+under=10101011100011000010010000
+up=10101011100011000010010001
+very=10101011100011000010010010
+video=10101011100011000010010011
+view=10101011100011000010010100
+vintage=10101011100011000010010101
+visit=10101011100011000010010110
+was=10101011100011000010010111
+way=10101011100011000010011000
+week=10101011100011000010011001
+well=10101011100011000010011010
+what=10101011100011000010011011
+when=10101011100011000010011100
+which=10101011100011000010011101
+while=10101011100011000010011110
+who=10101011100011000010011111
+will=10101011100011000010100000
+win=10101011100011000010100001
+with=10101011100011000010100010
+words=10101011100011000010100011
+world=10101011100011000010100100
+written=10101011100011000010100101
+year=100010001100
+you=10110011010
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyuk_astra2_28.4.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyuk_astra2_28.4.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyuk_astra2_28.4.conf	(revision 6505)
@@ -0,0 +1,13 @@
+description=Sky Uk OpenTV (Astra2 on 28.4)
+# nid ,tsid, sid
+nid=2
+tsid=2004
+sid=4152
+namespace=18612224
+# channels pids
+channels_pids=17
+# titles pids
+titles_pids=48|49|50|51|52|53|54|55
+# summaries pids
+summaries_pids=64|65|66|67|68|69|70|71
+protocol=opentv
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyuk_astra2_28.4.dict
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyuk_astra2_28.4.dict	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/skyuk_astra2_28.4.dict	(revision 6505)
@@ -0,0 +1,512 @@
+ =101010111000110000101001100
+ =101010111000110000101001101
+ =101010111000110000101001110
+ =101010111000110000101001111
+ =101010111000110000101010000
+ =101010111000110000101010001
+ =101010111000110000101010010
+ =101010111000110000101010011
+ =101010111000110000101010100
+=0001000
+ =1110111
+ =101010111000110000101010101
+ =101010111000110000101010110
+ =101010111000110000101010111
+ =101010111000110000101011000
+ =101010111000110000101011001
+ =101010111000110000101011010
+ =101010111000110000101011011
+ =101010111000110000101011100
+ =101010111000110000101011101
+ =101010111000110000101011110
+ =101010111000110000101011111
+ =101010111000110000101100000
+ =101010111000110000101100001
+ =101010111000110000101100010
+ =101010111000110000101100011
+ =101010111000110000101100100
+ =101010111000110000101100101
+ =101010111000110000101100110
+ =101010111000110000101100111
+ =101010111000110000101101000
+ =101010111000110000101101001
+ =110
+!=01000011000
+"=101010111000110000101101010
+#=101010111000110000101101011
+$=1010101110001101
+%=101010111000110000101101100
+&=10000011101
+'=10000010
+(=11101000101
+)=1010101100
+*=100010101110
++=101010111000110000101101101
+,=1011000
+-=10001011
+.=1110110
+/=00010100011110
+0=111010010
+1=101100111
+2=1000101000
+3=1000001111
+4=0001010000
+5=1110101000
+6=1000101001
+7=1000100010
+8=10001010110
+9=0100001101
+:=11101000110
+;=00010100010
+<=1110100011111
+==101010111000110000101101110
+>=1110101001100
+?=111010100111
+@=101010111000110001
+A=11100010
+B=01000000
+C=01000010
+D=111000111
+E=1110100000
+F=101010100
+G=100010000
+H=101010101
+I=1110100001
+J=000101001
+K=1110100111
+L=100000110
+M=10001001
+N=111010111
+O=010000010
+P=00010101
+Q=1000101010111
+R=111010110
+S=0001001
+T=0001011
+U=10101011101
+V=11101010101
+W=10110010
+X=1110001101101111
+Y=10101011110
+Z=1110101010000
+[=10101011100011001
+\=101010111000110000101101111
+]=11100011011011100
+^=101010111000110000101110000
+_=101010111000110000101110001
+`=11101010010
+a=1001
+b=1110000
+c=111001
+d=01001
+e=1111
+f=100001
+g=100011
+h=10111
+i=0101
+j=11100011010
+k=1000000
+l=10100
+m=101011
+n=0111
+o=0011
+p=000111
+q=10101011011
+r=0010
+s=0000
+t=0110
+u=101101
+v=1010100
+w=000110
+x=1110101011
+y=010001
+z=1011001100
+{=101010111000110000101110010
+|=101010111000110000101110011
+}=101010111000110000101110100
+~=101010111000110000101110101
+ =101010111000110000101110110
+ =101010111000110000101110111
+ =101010111000110000101111000
+ =101010111000110000101111001
+ =101010111000110000101111010
+ =101010111000110000101111011
+ =101010111000110000101111100
+ =101010111000110000101111101
+ =101010111000110000101111110
+ =101010111000110000101111111
+ =101010111000110000110000000
+ =101010111000110000110000001
+ =101010111000110000110000010
+ =101010111000110000110000011
+ =101010111000110000110000100
+ =101010111000110000110000101
+ =101010111000110000110000110
+ =101010111000110000110000111
+ =101010111000110000110001000
+ =101010111000110000110001001
+ =101010111000110000110001010
+ =101010111000110000110001011
+ =101010111000110000110001100
+ =101010111000110000110001101
+ =101010111000110000110001110
+ =101010111000110000110001111
+ =101010111000110000110010000
+ =101010111000110000110010001
+ =101010111000110000110010010
+ =11100011011011101
+ =101010111000110000110010011
+ =101010111000110000110010100
+ =101010111000110000110010101
+ =101010111000110000110010110
+¡=101010111000110000110010111
+¢=101010111000110000110011000
+£=101010111000110000110011001
+¤=101010111000110000110011010
+¥=101010111000110000110011011
+¦=101010111000110000110011100
+§=101010111000110000110011101
+¨=101010111000110000110011110
+©=101010111000110000110011111
+ª=101010111000110000110100000
+«=101010111000110000110100001
+¬=101010111000110000110100010
+­=101010111000110000110100011
+®=101010111000110000110100100
+¯=101010111000110000110100101
+°=101010111000110000110100110
+±=101010111000110000110100111
+²=101010111000110000110101000
+³=101010111000110000110101001
+´=101010111000110000110101010
+µ=101010111000110000110101011
+¶=101010111000110000110101100
+·=101010111000110000110101101
+¸=101010111000110000110101110
+¹=101010111000110000110101111
+º=101010111000110000110110000
+»=101010111000110000110110001
+¼=101010111000110000110110010
+½=101010111000110000110110011
+¾=101010111000110000110110100
+¿=101010111000110000110110101
+À=101010111000110000110110110
+Á=101010111000110000110110111
+Â=101010111000110000110111000
+Ã=101010111000110000110111001
+Ä=101010111000110000110111010
+Å=101010111000110000110111011
+Æ=101010111000110000110111100
+Ç=101010111000110000110111101
+È=101010111000110000110111110
+É=101010111000110000110111111
+Ê=101010111000110000111000000
+Ë=101010111000110000111000001
+Ì=101010111000110000111000010
+Í=101010111000110000111000011
+Î=101010111000110000111000100
+Ï=101010111000110000111000101
+Ð=101010111000110000111000110
+Ñ=101010111000110000111000111
+Ò=101010111000110000111001000
+Ó=101010111000110000111001001
+Ô=101010111000110000111001010
+Õ=101010111000110000111001011
+Ö=101010111000110000111001100
+×=101010111000110000111001101
+Ø=101010111000110000111001110
+Ù=101010111000110000111001111
+Ú=101010111000110000111010000
+Û=101010111000110000111010001
+Ü=101010111000110000111010010
+Ý=101010111000110000111010011
+Þ=101010111000110000111010100
+ß=101010111000110000111010101
+à=101010111000110000111010110
+á=101010111000110000111010111
+â=101010111000110000111011000
+ã=101010111000110000111011001
+ä=101010111000110000111011010
+å=101010111000110000111011011
+æ=101010111000110000111011100
+ç=101010111000110000111011101
+è=101010111000110000111011110
+é=101010111000110000111011111
+ê=101010111000110000111100000
+ë=101010111000110000111100001
+ì=101010111000110000111100010
+í=101010111000110000111100011
+î=101010111000110000111100100
+ï=101010111000110000111100101
+ð=101010111000110000111100110
+ñ=101010111000110000111100111
+ò=101010111000110000111101000
+ó=101010111000110000111101001
+ô=101010111000110000111101010
+õ=101010111000110000111101011
+ö=101010111000110000111101100
+÷=101010111000110000111101101
+ø=101010111000110000111101110
+ù=101010111000110000111101111
+ú=101010111000110000111110000
+û=101010111000110000111110001
+ü=101010111000110000111110010
+ý=101010111000110000111110011
+þ=101010111000110000111110100
+ÿ=101010111000110000111110101
+(Including =10101011111110
+(New Series)=11101000100010
+(Part =1110100011101
+(Repeat)=1110100110
+(Stereo)=010000111
+(Stereo) (Teletext)=010000011
+(Teletext)=1110001100
+(Widescreen)=100000111001110
+Action=101010111000111
+Adventures=10110011011111
+America=0100001100100
+Animated=111010100110111
+Australia=0100001100101
+Away=11101010100010
+BBC=10101011111111
+Baby=11100011011000
+Best=11101010100011
+Big=10110011011000
+Bill=1000101011111
+Black=1000101010000
+Blue=1011001101110
+Breakfast=000101000110
+Britain=1010101111100
+British=1110100011100
+Business=0100001100110
+Call=1010101111101
+Cartoon=10101011100000
+Channel=10101011100001
+Children=11101010100111
+Clock=11100011011001
+Comedy=11101000100011
+Cook=111010101001010
+Country=111010100110110
+Directed by =101010110100
+Drama=0100001100111
+East=1000101010001
+Education=100000111001111
+English=00010100011111
+Europe=0001010001110
+Extra=10110011011001
+Final=10101011100010
+Financial=111000110110100
+For=111000110111
+French=11101000111101
+From=1000101010010
+George=1010101111110
+Get=1000100011010
+Girls=10001000110110
+Golden=10001000110111
+Golf=111010101001011
+Good=1010101101010
+Great=11101000100100
+Hampshire=111010101001100
+Headlines=1000101010011
+Hear=11101010011010
+Hill=1000001110000
+Hollywood=111000110110101
+Home=1000101010100
+Hour=11101000100101
+House=1000001110010
+How=1010101101011
+ITN=11101010100100
+Important=111010101001101
+Including=1000101011110
+International=11101000100110
+John=10001000111
+Last=11101000100111
+Late=10000011100110
+Learn=10001010101100
+Little=10001010101101
+Live=1110100010000
+London=11101000111100
+Look=10110011011110
+Lunch=111000110110110
+Man=1000101010101
+Mark=1000001110001
+Meridian=101010111001
+Michael=1011001101101
+Minutes=101010111000110000111110110
+More=101010111000110000111110111
+Morning=101010111000110000111111000
+Murder=101010111000110000111111001
+Nation=101010111000110000111111010
+Neighbours=101010111000110000111111011
+New=101010111000110000111111100
+News & Weather=101010111000110000111111101
+News And Weather=101010111000110000111111110
+Paul=101010111000110000111111111
+Plus=10101011100011000000000000
+Prayer=10101011100011000000000001
+Present=10101011100011000000000010
+Presented by=10101011100011000000000011
+Quiz=10101011100011000000000100
+Regional=10101011100011000000000101
+Represent=10101011100011000000000110
+Resource=10101011100011000000000111
+Review=10101011100011000000001000
+Richard=10101011100011000000001001
+School=10101011100011000000001010
+Series=10101011100011000000001011
+Service=10101011100011000000001100
+Show=10101011100011000000001101
+Smith=10101011100011000000001110
+South=10101011100011000000001111
+Sport=10101011100011000000010000
+Star=10101011100011000000010001
+Street=10101011100011000000010010
+TV=10101011100011000000010011
+Teaching=10101011100011000000010100
+The=10101011100011000000010101
+Today=10101011100011000000010110
+Tonight=10101011100011000000010111
+Weather=10101011100011000000011000
+Western=10101011100011000000011001
+Westminster=10101011100011000000011010
+William=10101011100011000000011011
+With=10101011100011000000011100
+World=10101011100011000000011101
+about=10101011100011000000011110
+action-packed=10101011100011000000011111
+adventure=10101011100011000000100000
+afternoon=10101011100011000000100001
+alert=10101011100011000000100010
+all-star cast=10101011100011000000100011
+and=10101011100011000000100100
+anywhere=10101011100011000000100101
+audience=10101011100011000000100110
+based=10101011100011000000100111
+book=10101011100011000000101000
+business=10101011100011000000101001
+but=10101011100011000000101010
+celebrity=10101011100011000000101011
+chance=10101011100011000000101100
+chat=10101011100011000000101101
+child=10101011100011000000101110
+classic=10101011100011000000101111
+consumer=10101011100011000000110000
+contestants=10101011100011000000110001
+continues=10101011100011000000110010
+controversial=10101011100011000000110011
+dealer=10101011100011000000110100
+deliver=10101011100011000000110101
+discuss=10101011100011000000110110
+document=10101011100011000000110111
+drama=10101011100011000000111000
+edition=10101011100011000000111001
+education=10101011100011000000111010
+events=10101011100011000000111011
+every=10101011100011000000111100
+excellent=10101011100011000000111101
+eyed=10101011100011000000111110
+family=10101011100011000000111111
+famous=10101011100011000001000000
+featur=10101011100011000001000001
+film=10101011100011000001000010
+football=10101011100011000001000011
+for=10101011100011000001000100
+from=10101011100011000001000101
+general knowledge=10101011100011000001000110
+get=10101011100011000001000111
+guest=10101011100011000001001000
+guests=10101011100011000001001001
+has=10101011100011000001001010
+have=10101011100011000001001011
+headline=10101011100011000001001100
+her=10101011100011000001001101
+his=10101011100011000001001110
+home and abroad=10101011100011000001001111
+host=10101011100011000001010000
+how=10101011100011000001010001
+in=10101011100011000001010010
+including=10101011100011000001010011
+international=10101011100011000001010100
+interview=10101011100011000001010101
+introduce=10101011100011000001010110
+investigat=10101011100011000001010111
+invites=10101011100011000001011000
+issue=10101011100011000001011001
+knowledge=10101011100011000001011010
+life=10101011100011000001011011
+live=10101011100011000001011100
+look=10101011100011000001011101
+magazine=10101011100011000001011110
+meets =10101011100011000001011111
+morning=10101011100011000001100000
+morning magazine=10101011100011000001100001
+music=10101011100011000001100010
+near=10101011100011000001100011
+network=10101011100011000001100100
+new=10101011100011000001100101
+new series=10101011100011000001100110
+night=10101011100011000001100111
+of=10101011100011000001101000
+on=10101011100011000001101001
+onight=10101011100011000001101010
+out=10101011100011000001101011
+over=10101011100011000001101100
+part=10101011100011000001101101
+people=10101011100011000001101110
+phone=10101011100011000001101111
+poli=10101011100011000001110000
+police=10101011100011000001110001
+political chat show=10101011100011000001110010
+popular=10101011100011000001110011
+presented by =10101011100011000001110100
+programm=10101011100011000001110101
+quiz=10101011100011000001110110
+reconstruction=10101011100011000001110111
+report=10101011100011000001111000
+review=10101011100011000001111001
+school=10101011100011000001111010
+series=10101011100011000001111011
+short =10101011100011000001111100
+show=10101011100011000001111101
+some=10101011100011000001111110
+starring=10101011100011000001111111
+stars=10101011100011000010000000
+stories=10101011100011000010000001
+story=10101011100011000010000010
+studio=10101011100011000010000011
+surprise=10101011100011000010000100
+teller=10101011100011000010000101
+that=10101011100011000010000110
+the=10101011100011000010000111
+their=10101011100011000010001000
+them=10101011100011000010001001
+they=10101011100011000010001010
+this=10101011100011000010001011
+through=10101011100011000010001100
+to=10101011100011000010001101
+top=10101011100011000010001110
+trans=10101011100011000010001111
+under=10101011100011000010010000
+up=10101011100011000010010001
+very=10101011100011000010010010
+video=10101011100011000010010011
+view=10101011100011000010010100
+vintage=10101011100011000010010101
+visit=10101011100011000010010110
+was=10101011100011000010010111
+way=10101011100011000010011000
+week=10101011100011000010011001
+well=10101011100011000010011010
+what=10101011100011000010011011
+when=10101011100011000010011100
+which=10101011100011000010011101
+while=10101011100011000010011110
+who=10101011100011000010011111
+will=10101011100011000010100000
+win=10101011100011000010100001
+with=10101011100011000010100010
+words=10101011100011000010100011
+world=10101011100011000010100100
+written=10101011100011000010100101
+year=100010001100
+you=10110011010
Index: ipk/source/epg_crossepg_0_61/var/crossepg/providers/test_script.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/providers/test_script.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/providers/test_script.conf	(revision 6505)
@@ -0,0 +1,3 @@
+protocol=script
+filename=test.py
+description=example test script (do nothing)
Index: ipk/source/epg_crossepg_0_61/var/crossepg/scripts/alias/alias.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/scripts/alias/alias.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/scripts/alias/alias.conf	(revision 6505)
@@ -0,0 +1,59 @@
+# alias.conf by ambrosa http://www.ambrosa.net
+# configuration file
+# 
+
+# how to setup [aliases] section
+#
+# format:
+# SOURCE=DESTINATION
+# epg data will be copied from SOURCE to DESTINATION
+#
+# SOURCE is:
+# channel_name-provider_name
+#
+#   or
+#
+# SID-TSID-ONID
+# i.e. 0002:00820000:1770:0110:1:0
+#       SID:   ns   :TSID:ONID:stype:unused
+# SID = 0002  TSID = 1770  ONID = 0110
+#
+#
+# DESTINATION is:
+# channel_name[,channel_name...]
+#
+#
+# Examples:
+# canale5-mediaset=canale 5
+# epg data from "canale 5" provider "mediaset" will be copied to "canale 5" (every provider)
+#
+# canale5-mediaset=canale 5,canale cinque,canale5
+# epg data from "canale 5" provider "mediaset" will be copied to "canale 5" (every provider) and
+# to "canale cinque" (every provider) and to "canale5" (same name as source but different provider than "mediaset")
+#
+# 0002-1770-0110=canale 5
+# epg data from sid "0002:00820000:1770:0110:1:0" will be copied to "canale 5" (every provider)
+#
+# 0002-1770-0110=canale 5,canale cinque,canale5
+# epg data from "0002:00820000:1770:0110:1:0"  will be copied to "canale 5" (every provider) and
+# to "canale cinque" (every provider) and to "canale5" (every provider)
+#
+#
+#
+# note 1: channel_name and provider_name are case insensitive
+#
+# note 2: SID/TSID/ONID can be read using remote control MENU->INFORMATION->CURRENT CHANNEL INFORMATION
+#         ServiceReference looks like 
+#         1:0:19:106A:2008:FBFF:820000:0:0: 
+#         the format is
+#         1:0:19:SID :TSID:ONID:820000:0:0:
+#         so the SOURCE will be: 
+#         106A-2008-FBFF=.......
+
+
+# ALIASES configuration section
+[aliases]
+
+
+canale 5-mediaset=canale 5,canale5
+
Index: ipk/source/epg_crossepg_0_61/var/crossepg/scripts/alias/alias.py
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/scripts/alias/alias.py	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/scripts/alias/alias.py	(revision 6505)
@@ -0,0 +1,234 @@
+#!/usr/bin/python
+# alias.py  by Ambrosa http://www.ambrosa.net
+# this module is used for copy epg from a channel to another
+
+__author__ = "ambrosa http://www.ambrosa.net"
+__copyright__ = "Copyright (C) 2008-2011 Alessandro Ambrosini"
+__license__ = "CreativeCommons by-nc-sa http://creativecommons.org/licenses/by-nc-sa/3.0/"
+
+import os
+import sys
+import ConfigParser
+
+# import CrossEPG functions
+import crossepg
+
+# location of local python modules under "scripts/lib" dir.
+# add it to sys.path()
+crossepg_instroot = crossepg.epgdb_get_installroot()
+if crossepg_instroot == False:
+	sys.exit(1)
+libdir = os.path.join(crossepg_instroot , 'scripts/lib')
+sys.path.append(libdir)
+
+# import local modules
+import sgmllib
+import scriptlib
+
+
+class main:
+
+	# main config file
+	CONF_CONFIGFILENAME = "alias.conf"
+
+	# log text
+	CONF_LOG_SCRIPT_NAME = "ALIAS EPG"
+	CONF_LOG_PREFIX = "ALIAS "
+
+
+	def log(self,s,video=0):
+		self.logging.log(self.CONF_LOG_PREFIX + str(s))
+		if video == 1:
+			self.log2video(str(s))
+
+	def log2video(self,s):
+		self.logging.log2video_status(str(s))
+
+
+
+	def __init__(self,confdir,dbroot):
+
+		# initialize logging
+		self.logging = scriptlib.logging_class()
+		# write to video OSD the script name
+		self.logging.log2video_scriptname(self.CONF_LOG_SCRIPT_NAME)
+
+
+		CONF_FILE = os.path.join(confdir,self.CONF_CONFIGFILENAME)
+		if not os.path.exists(CONF_FILE) :
+			self.log("ERROR: %s not present" % CONF_FILE)
+			sys.exit(1)
+
+		config = ConfigParser.ConfigParser()
+		#config.optionxform = str  # needed to return case sensitive index
+		config.read(CONF_FILE)
+
+		# reading [aliases] section
+		temp=config.items("aliases");
+
+		self.CHANNELLIST = {}
+		# create a dictionary (Python array) with index = channel ID
+		for i in temp:
+			self.CHANNELLIST[i[0]] = unicode(i[1],'utf-8')
+
+		if len(self.CHANNELLIST) == 0 :
+			self.log("ERROR: [aliases] section empty ?")
+			sys.exit(1)
+
+
+# ----------------------------------------------------------------------
+
+
+	def do_epg_alias(self):
+		self.log("--- START PROCESSING ---")
+		self.log("Loading lamedb indexed by channel name")
+		lamedb = scriptlib.lamedb_class()
+
+		self.log("Initialize CrossEPG database")
+		crossdb = scriptlib.crossepg_db_class()
+		crossdb.open_db()
+
+		total_events = 0
+
+		for src_channel in self.CHANNELLIST :
+
+			dst_channels = self.CHANNELLIST[src_channel].split(',')
+
+			if src_channel.count('-') == 1 :
+				src_chname = src_channel.split('-')[0].strip(' \n\r').lower()
+				src_provname = src_channel.split('-')[1].strip(' \n\r').lower()
+
+				src_sidbyname = []
+				src_sidprovidbyname = lamedb.get_sidprovid_byname(src_chname)
+				for p in src_sidprovidbyname:
+					if p[1] == src_provname :
+						# a channel can have zero or more SID (different channel with same name)
+						# return the list [ 0e1f:00820000:0708:00c8:1:0 , 1d20:00820000:2fa8:013e:1:0 , ..... ]
+						# return [] if channel name is not in lamedb
+						src_sidbyname = p[0]
+						ch_sid = lamedb.convert_sid(src_sidbyname)
+						if len(ch_sid) == 0 :
+							self.log("SID \"%s\" invalid, try next" % src_sidbyname)
+							continue
+
+						src_epgdb_channel = crossepg.epgdb_channels_get_by_freq(ch_sid[2],ch_sid[1],ch_sid[0]);
+						if not src_epgdb_channel :
+							self.log('Source channel "%s" with SID "%s" has not entry in epgdb, try next' % (src_channel,src_sidbyname) )
+							continue
+						else:
+							break
+
+				# if not sid then exit, go ahead with next src_channel
+				if len(src_sidbyname) == 0:
+					self.log('Source channel "%s" has not SID in lamedb, skip it' % src_channel)
+					continue
+
+			elif src_channel.count('-') == 2 :
+				tmp = src_channel.split('-')
+				src_sidbyname = "%s:xxxxxxxx:%s:%s:x:x" %(tmp[0].strip(' \n\r'),tmp[1].strip(' \n\r'),tmp[2].strip(' \n\r'))
+
+			else:
+				self.log("Channel source \"%s\" invalid" % src_channel)
+				continue
+
+			# convert "0e1f:00820000:0708:00c8:1:0" to sid,tsid,onid
+			# return the list [sid,tsid,onid]
+			src_sid = lamedb.convert_sid(src_sidbyname)
+			if len(src_sid) == 0 :
+				self.log("SID \"%s\" invalid, try next" % src_sidbyname)
+				continue
+
+			src_epgdb_channel = crossepg.epgdb_channels_get_by_freq(src_sid[2],src_sid[1],src_sid[0]);
+			if not src_epgdb_channel :
+				self.log('Source channel "%s" with SID "%s" has not entry in epgdb, skip it' % (src_channel,src_sidbyname) )
+				continue
+
+			self.log('Source channel "%s" with SID "%s" found in epgdb, using it' % (src_channel,src_sidbyname) )
+
+			for dst in dst_channels:
+				dst = dst.strip(' \n\r').lower()
+				dst_sidbyname = lamedb.get_sid_byname(dst)
+				if len(dst_sidbyname) == 0:
+					self.log('   dest. channel "%s" has not SID in lamedb, skip it' % dst)
+					continue
+
+				for dsid in dst_sidbyname:
+
+					# convert "0e1f:00820000:0708:00c8:1:0" to sid,tsid,onid
+					# return the list [sid,tsid,onid]
+					dst_sid = lamedb.convert_sid(dsid)
+
+					if dst_sid == src_sid:
+						# skip if source=destination
+						self.log('   dest. channel "%s" is eq. to source, skip it' % dst)
+						continue
+
+					num_events = 0
+					self.log('   copying EPG data from "%s" to "%s" sid "%s")' % (src_channel,dst,dsid) )
+					self.log2video("%s -> %s (%d/%d)" % (src_channel,dst,num_events,total_events))
+
+
+					# add channel into db
+					# doesn't matter if the channel already exist... epgdb do all the work
+					# this make a reference to the dest. channel
+					crossdb.add_channel(dst_sid)
+
+					title = src_epgdb_channel.title_first;
+
+					while (title != None) :
+						#print str(title.start_time)
+						#print str(title.length)
+						#print str(crossepg.epgdb_read_description(title))
+						#print str(crossepg.epgdb_read_long_description(title))
+						#print "-----------------------------------"
+
+						e_starttime = int(title.start_time)
+						e_length = int(title.length)
+						e_title = crossepg.epgdb_read_description(title).encode('utf-8')
+						e_summarie = crossepg.epgdb_read_long_description(title).encode('utf-8')
+						e_countrycode = "%c%c%c" % (title.iso_639_1, title.iso_639_2, title.iso_639_3)
+
+						# add_event(start_time , duration , title , summarie , ISO639_language_code , strings_encoded_with_UTF-8)
+						crossdb.add_event(e_starttime, e_length, e_title, e_summarie, e_countrycode, True )
+						num_events += 1
+						title = title.next
+
+						if (num_events % 25) == 0:
+							self.log2video("%s -> %s (%d/%d)" % (src_channel,dst,num_events,total_events))
+
+
+					total_events += num_events
+					self.log("   copied %d events" % num_events)
+
+		self.log2video("end: copied %d events" % (total_events))
+		# end process, close CrossEPG DB saving data
+		crossdb.close_db()
+		self.log("Copied %d events" % total_events)
+		self.log("--- END ---")
+
+
+
+# ****************************************************************************************************************************
+
+# MAIN CODE: SCRIPT START HERE
+
+SCRIPT_DIR = 'scripts/alias/'
+
+# get CrossEPG installation dir.
+crossepg_instroot = crossepg.epgdb_get_installroot()
+if crossepg_instroot == False:
+	sys.exit(1)
+scriptlocation = os.path.join(crossepg_instroot , SCRIPT_DIR)
+
+# get where CrossEPG save data (dbroot) and use it as script cache repository
+crossepg_dbroot = crossepg.epgdb_get_dbroot()
+if crossepg_dbroot == False:
+	sys.exit(1)
+
+# initialize script class
+script_class = main(scriptlocation , crossepg_dbroot)
+
+# copy epg
+script_class.do_epg_alias()
+
+
Index: ipk/source/epg_crossepg_0_61/var/crossepg/scripts/example_script.py
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/scripts/example_script.py	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/scripts/example_script.py	(revision 6505)
@@ -0,0 +1,128 @@
+#!/usr/bin/python
+# Author: Skaman
+# Date: October 2010
+
+from crossepg import *
+
+def dump_title(title):
+	log_add("----------EVENT----------")
+	log_add("ID: %d" % title.event_id)
+	log_add("MJD: %d" % title.mjd)
+	log_add("START TIME: %d" % title.start_time)
+	log_add("DURATION: %d" % title.length)
+	log_add("GENRE ID: %d" % title.genre_id)
+	log_add("REVISION: %d" % title.revision)
+	log_add("ISO639: %c%c%c" % (title.iso_639_1, title.iso_639_2, title.iso_639_3))
+	log_add("IS UTF8: %d" % IS_UTF8(title.flags))
+	log_add("DESCRIPTION_CRC: 0x%x" % title.description_crc)
+	log_add("DESCRIPTION_SEEK: %d" % title.description_seek)
+	log_add("DESCRIPTION LENTH: %d" % title.description_length)
+	log_add("DESCRIPTION: %s" % epgdb_read_description(title))
+	log_add("LONG DESCRIPTION CRC: 0x%x" % title.long_description_crc)
+	log_add("LONG DESCRIPTION SEEK: %d" % title.long_description_seek)
+	log_add("LONG DESCRIPTION LENTH: %d" % title.long_description_length)
+	log_add("LONG DESCRIPTION: %s" % epgdb_read_long_description(title))
+
+def main():
+	# get dbroot path
+	dbroot = epgdb_get_dbroot()
+
+	# open epgdb
+	if epgdb_open(dbroot):
+		log_add("EPGDB opened (root=%s)" % dbroot);
+	else:
+		log_add("Error opening EPGDB");
+		epgdb_close();
+		return
+
+	# load indexes and hashes in memory
+	epgdb_load();
+
+	####################
+	# WRITE OPERATIONS #
+	####################
+
+	# add an event into db
+	log_add("TEST: add an event into db")
+	nid = 0x01		# original network id
+	tsid = 0x01		# transport service id
+	sid = 0x01		# service id
+					# the 3 values above identify the channel
+
+	channel = epgdb_channels_add(nid, tsid, sid)	# add channel into db and get a reference to the structure
+													# doesn't matter if the channel already exist... epgdb do all the work
+
+	title = epgdb_title_alloc()							# alloc title structure in memory
+	title.event_id = 1									# event id.. it's unique inside a channel
+	title.start_time = 1293840000						# 1/1/2011 timestamp.. it's always referred to gmt+0 without daylight saving
+	title.mjd = epgdb_calculate_mjd(title.start_time)	# Modified Julian Date.. if you don't know it you can calulate it with epgdb_calculate_mjd()
+	title.length = 600									# ten minutes.. event duration in seconds
+	title.iso_639_1 = ord('e')							# ISO 639 language code.. http://en.wikipedia.org/wiki/ISO_639
+	title.iso_639_2 = ord('n')
+	title.iso_639_3 = ord('g')
+
+	title.flags = SET_UTF8(title.flags)		# necessary only if description and/or long description have utf-8 charset
+
+	title = epgdb_titles_add(channel, title)	# add event in epgdb and return back a reference to the structure
+												# remember to use always the new structure reference
+												# if the event already exist epgdb update it and automatically destroy the new structure
+
+	# now the event structure is already in epgdb
+	# but we still need to add descriptions
+	epgdb_titles_set_description (title, "our custom event short description");
+	epgdb_titles_set_long_description (title, "our custom event long description");
+
+	###################
+	# READ OPERATIONS #
+	###################
+
+	# walk inside channels and events
+	log_add("TEST: walk inside channels and events")
+	channel_count = 0
+	channel = epgdb_channels_get_first();
+	while channel != None:
+		log_add("---------CHANNEL---------")
+		log_add("NID: 0x%x" % channel.nid)
+		log_add("TSID: 0x%x" % channel.tsid)
+		log_add("SID: 0x%x" % channel.sid)
+		title_count = 0
+		title = channel.title_first;
+		while title != None:
+			dump_title(title)
+			title = title.next
+			title_count += 1
+			if title_count == 2:		# it's only a test so we halt the loop after 2 titles
+				break
+
+		channel = channel.next
+		channel_count += 1
+		if channel_count == 3:		# it's only a test so we halt the loop after 3 channels
+			break
+
+	# get a channel by nid, tsid, sid
+	log_add("TEST: get a channel by nid, tsid, sid")
+	channel = epgdb_channels_get_by_freq(nid, tsid, sid);
+	if channel:
+		# get an event by channel and timestamp
+		log_add("TEST: get an event by channel and timestamp")
+		title = epgdb_titles_get_by_time (channel, 1293840000); # exist also the api epgdb_titles_get_by_id_and_mjd(channel, event_id, mjd_time)
+		if title:
+			dump_title(title)
+		else:
+			log_add("Title not found")
+	else:
+		log_add("Channel not found")
+
+	# saving data
+	# it's necessary only if you add new events
+	if epgdb_save(None):
+		log_add("Data saved");
+	else:
+		log_add("Error saving data");
+
+	# close epgdb and clean memory
+	epgdb_close()
+	epgdb_clean()
+	log_add("EPGDB closed");
+
+main()
Index: ipk/source/epg_crossepg_0_61/var/crossepg/scripts/lib/__init__.py
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/scripts/lib/__init__.py	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/scripts/lib/__init__.py	(revision 6505)
@@ -0,0 +1,2 @@
+# empty file
+
Index: ipk/source/epg_crossepg_0_61/var/crossepg/scripts/lib/markupbase.py
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/scripts/lib/markupbase.py	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/scripts/lib/markupbase.py	(revision 6505)
@@ -0,0 +1,392 @@
+"""Shared support for scanning document type declarations in HTML and XHTML.
+
+This module is used as a foundation for the HTMLParser and sgmllib
+modules (indirectly, for htmllib as well).  It has no documented
+public API and should not be used directly.
+
+"""
+
+import re
+
+_declname_match = re.compile(r'[a-zA-Z][-_.a-zA-Z0-9]*\s*').match
+_declstringlit_match = re.compile(r'(\'[^\']*\'|"[^"]*")\s*').match
+_commentclose = re.compile(r'--\s*>')
+_markedsectionclose = re.compile(r']\s*]\s*>')
+
+# An analysis of the MS-Word extensions is available at
+# http://www.planetpublish.com/xmlarena/xap/Thursday/WordtoXML.pdf
+
+_msmarkedsectionclose = re.compile(r']\s*>')
+
+del re
+
+
+class ParserBase:
+    """Parser base class which provides some common support methods used
+    by the SGML/HTML and XHTML parsers."""
+
+    def __init__(self):
+        if self.__class__ is ParserBase:
+            raise RuntimeError(
+                "markupbase.ParserBase must be subclassed")
+
+    def error(self, message):
+        raise NotImplementedError(
+            "subclasses of ParserBase must override error()")
+
+    def reset(self):
+        self.lineno = 1
+        self.offset = 0
+
+    def getpos(self):
+        """Return current line number and offset."""
+        return self.lineno, self.offset
+
+    # Internal -- update line number and offset.  This should be
+    # called for each piece of data exactly once, in order -- in other
+    # words the concatenation of all the input strings to this
+    # function should be exactly the entire input.
+    def updatepos(self, i, j):
+        if i >= j:
+            return j
+        rawdata = self.rawdata
+        nlines = rawdata.count("\n", i, j)
+        if nlines:
+            self.lineno = self.lineno + nlines
+            pos = rawdata.rindex("\n", i, j) # Should not fail
+            self.offset = j-(pos+1)
+        else:
+            self.offset = self.offset + j-i
+        return j
+
+    _decl_otherchars = ''
+
+    # Internal -- parse declaration (for use by subclasses).
+    def parse_declaration(self, i):
+        # This is some sort of declaration; in "HTML as
+        # deployed," this should only be the document type
+        # declaration ("<!DOCTYPE html...>").
+        # ISO 8879:1986, however, has more complex
+        # declaration syntax for elements in <!...>, including:
+        # --comment--
+        # [marked section]
+        # name in the following list: ENTITY, DOCTYPE, ELEMENT,
+        # ATTLIST, NOTATION, SHORTREF, USEMAP,
+        # LINKTYPE, LINK, IDLINK, USELINK, SYSTEM
+        rawdata = self.rawdata
+        j = i + 2
+        assert rawdata[i:j] == "<!", "unexpected call to parse_declaration"
+        if rawdata[j:j+1] == ">":
+            # the empty comment <!>
+            return j + 1
+        if rawdata[j:j+1] in ("-", ""):
+            # Start of comment followed by buffer boundary,
+            # or just a buffer boundary.
+            return -1
+        # A simple, practical version could look like: ((name|stringlit) S*) + '>'
+        n = len(rawdata)
+        if rawdata[j:j+2] == '--': #comment
+            # Locate --.*-- as the body of the comment
+            return self.parse_comment(i)
+        elif rawdata[j] == '[': #marked section
+            # Locate [statusWord [...arbitrary SGML...]] as the body of the marked section
+            # Where statusWord is one of TEMP, CDATA, IGNORE, INCLUDE, RCDATA
+            # Note that this is extended by Microsoft Office "Save as Web" function
+            # to include [if...] and [endif].
+            return self.parse_marked_section(i)
+        else: #all other declaration elements
+            decltype, j = self._scan_name(j, i)
+        if j < 0:
+            return j
+        if decltype == "doctype":
+            self._decl_otherchars = ''
+        while j < n:
+            c = rawdata[j]
+            if c == ">":
+                # end of declaration syntax
+                data = rawdata[i+2:j]
+                if decltype == "doctype":
+                    self.handle_decl(data)
+                else:
+                    self.unknown_decl(data)
+                return j + 1
+            if c in "\"'":
+                m = _declstringlit_match(rawdata, j)
+                if not m:
+                    return -1 # incomplete
+                j = m.end()
+            elif c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ":
+                name, j = self._scan_name(j, i)
+            elif c in self._decl_otherchars:
+                j = j + 1
+            elif c == "[":
+                # this could be handled in a separate doctype parser
+                if decltype == "doctype":
+                    j = self._parse_doctype_subset(j + 1, i)
+                elif decltype in ("attlist", "linktype", "link", "element"):
+                    # must tolerate []'d groups in a content model in an element declaration
+                    # also in data attribute specifications of attlist declaration
+                    # also link type declaration subsets in linktype declarations
+                    # also link attribute specification lists in link declarations
+                    self.error("unsupported '[' char in %s declaration" % decltype)
+                else:
+                    self.error("unexpected '[' char in declaration")
+            else:
+                self.error(
+                    "unexpected %r char in declaration" % rawdata[j])
+            if j < 0:
+                return j
+        return -1 # incomplete
+
+    # Internal -- parse a marked section
+    # Override this to handle MS-word extension syntax <![if word]>content<![endif]>
+    def parse_marked_section(self, i, report=1):
+        rawdata= self.rawdata
+        assert rawdata[i:i+3] == '<![', "unexpected call to parse_marked_section()"
+        sectName, j = self._scan_name( i+3, i )
+        if j < 0:
+            return j
+        if sectName in ("temp", "cdata", "ignore", "include", "rcdata"):
+            # look for standard ]]> ending
+            match= _markedsectionclose.search(rawdata, i+3)
+        elif sectName in ("if", "else", "endif"):
+            # look for MS Office ]> ending
+            match= _msmarkedsectionclose.search(rawdata, i+3)
+        else:
+            self.error('unknown status keyword %r in marked section' % rawdata[i+3:j])
+        if not match:
+            return -1
+        if report:
+            j = match.start(0)
+            self.unknown_decl(rawdata[i+3: j])
+        return match.end(0)
+
+    # Internal -- parse comment, return length or -1 if not terminated
+    def parse_comment(self, i, report=1):
+        rawdata = self.rawdata
+        if rawdata[i:i+4] != '<!--':
+            self.error('unexpected call to parse_comment()')
+        match = _commentclose.search(rawdata, i+4)
+        if not match:
+            return -1
+        if report:
+            j = match.start(0)
+            self.handle_comment(rawdata[i+4: j])
+        return match.end(0)
+
+    # Internal -- scan past the internal subset in a <!DOCTYPE declaration,
+    # returning the index just past any whitespace following the trailing ']'.
+    def _parse_doctype_subset(self, i, declstartpos):
+        rawdata = self.rawdata
+        n = len(rawdata)
+        j = i
+        while j < n:
+            c = rawdata[j]
+            if c == "<":
+                s = rawdata[j:j+2]
+                if s == "<":
+                    # end of buffer; incomplete
+                    return -1
+                if s != "<!":
+                    self.updatepos(declstartpos, j + 1)
+                    self.error("unexpected char in internal subset (in %r)" % s)
+                if (j + 2) == n:
+                    # end of buffer; incomplete
+                    return -1
+                if (j + 4) > n:
+                    # end of buffer; incomplete
+                    return -1
+                if rawdata[j:j+4] == "<!--":
+                    j = self.parse_comment(j, report=0)
+                    if j < 0:
+                        return j
+                    continue
+                name, j = self._scan_name(j + 2, declstartpos)
+                if j == -1:
+                    return -1
+                if name not in ("attlist", "element", "entity", "notation"):
+                    self.updatepos(declstartpos, j + 2)
+                    self.error(
+                        "unknown declaration %r in internal subset" % name)
+                # handle the individual names
+                meth = getattr(self, "_parse_doctype_" + name)
+                j = meth(j, declstartpos)
+                if j < 0:
+                    return j
+            elif c == "%":
+                # parameter entity reference
+                if (j + 1) == n:
+                    # end of buffer; incomplete
+                    return -1
+                s, j = self._scan_name(j + 1, declstartpos)
+                if j < 0:
+                    return j
+                if rawdata[j] == ";":
+                    j = j + 1
+            elif c == "]":
+                j = j + 1
+                while j < n and rawdata[j].isspace():
+                    j = j + 1
+                if j < n:
+                    if rawdata[j] == ">":
+                        return j
+                    self.updatepos(declstartpos, j)
+                    self.error("unexpected char after internal subset")
+                else:
+                    return -1
+            elif c.isspace():
+                j = j + 1
+            else:
+                self.updatepos(declstartpos, j)
+                self.error("unexpected char %r in internal subset" % c)
+        # end of buffer reached
+        return -1
+
+    # Internal -- scan past <!ELEMENT declarations
+    def _parse_doctype_element(self, i, declstartpos):
+        name, j = self._scan_name(i, declstartpos)
+        if j == -1:
+            return -1
+        # style content model; just skip until '>'
+        rawdata = self.rawdata
+        if '>' in rawdata[j:]:
+            return rawdata.find(">", j) + 1
+        return -1
+
+    # Internal -- scan past <!ATTLIST declarations
+    def _parse_doctype_attlist(self, i, declstartpos):
+        rawdata = self.rawdata
+        name, j = self._scan_name(i, declstartpos)
+        c = rawdata[j:j+1]
+        if c == "":
+            return -1
+        if c == ">":
+            return j + 1
+        while 1:
+            # scan a series of attribute descriptions; simplified:
+            #   name type [value] [#constraint]
+            name, j = self._scan_name(j, declstartpos)
+            if j < 0:
+                return j
+            c = rawdata[j:j+1]
+            if c == "":
+                return -1
+            if c == "(":
+                # an enumerated type; look for ')'
+                if ")" in rawdata[j:]:
+                    j = rawdata.find(")", j) + 1
+                else:
+                    return -1
+                while rawdata[j:j+1].isspace():
+                    j = j + 1
+                if not rawdata[j:]:
+                    # end of buffer, incomplete
+                    return -1
+            else:
+                name, j = self._scan_name(j, declstartpos)
+            c = rawdata[j:j+1]
+            if not c:
+                return -1
+            if c in "'\"":
+                m = _declstringlit_match(rawdata, j)
+                if m:
+                    j = m.end()
+                else:
+                    return -1
+                c = rawdata[j:j+1]
+                if not c:
+                    return -1
+            if c == "#":
+                if rawdata[j:] == "#":
+                    # end of buffer
+                    return -1
+                name, j = self._scan_name(j + 1, declstartpos)
+                if j < 0:
+                    return j
+                c = rawdata[j:j+1]
+                if not c:
+                    return -1
+            if c == '>':
+                # all done
+                return j + 1
+
+    # Internal -- scan past <!NOTATION declarations
+    def _parse_doctype_notation(self, i, declstartpos):
+        name, j = self._scan_name(i, declstartpos)
+        if j < 0:
+            return j
+        rawdata = self.rawdata
+        while 1:
+            c = rawdata[j:j+1]
+            if not c:
+                # end of buffer; incomplete
+                return -1
+            if c == '>':
+                return j + 1
+            if c in "'\"":
+                m = _declstringlit_match(rawdata, j)
+                if not m:
+                    return -1
+                j = m.end()
+            else:
+                name, j = self._scan_name(j, declstartpos)
+                if j < 0:
+                    return j
+
+    # Internal -- scan past <!ENTITY declarations
+    def _parse_doctype_entity(self, i, declstartpos):
+        rawdata = self.rawdata
+        if rawdata[i:i+1] == "%":
+            j = i + 1
+            while 1:
+                c = rawdata[j:j+1]
+                if not c:
+                    return -1
+                if c.isspace():
+                    j = j + 1
+                else:
+                    break
+        else:
+            j = i
+        name, j = self._scan_name(j, declstartpos)
+        if j < 0:
+            return j
+        while 1:
+            c = self.rawdata[j:j+1]
+            if not c:
+                return -1
+            if c in "'\"":
+                m = _declstringlit_match(rawdata, j)
+                if m:
+                    j = m.end()
+                else:
+                    return -1    # incomplete
+            elif c == ">":
+                return j + 1
+            else:
+                name, j = self._scan_name(j, declstartpos)
+                if j < 0:
+                    return j
+
+    # Internal -- scan a name token and the new position and the token, or
+    # return -1 if we've reached the end of the buffer.
+    def _scan_name(self, i, declstartpos):
+        rawdata = self.rawdata
+        n = len(rawdata)
+        if i == n:
+            return None, -1
+        m = _declname_match(rawdata, i)
+        if m:
+            s = m.group()
+            name = s.strip()
+            if (i + len(s)) == n:
+                return None, -1  # end of buffer
+            return name.lower(), m.end()
+        else:
+            self.updatepos(declstartpos, i)
+            self.error("expected name token at %r"
+                       % rawdata[declstartpos:declstartpos+20])
+
+    # To be overridden -- handlers for unknown objects
+    def unknown_decl(self, data):
+        pass
Index: ipk/source/epg_crossepg_0_61/var/crossepg/scripts/lib/scriptlib.py
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/scripts/lib/scriptlib.py	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/scripts/lib/scriptlib.py	(revision 6505)
@@ -0,0 +1,366 @@
+#!/usr/bin/python
+# scriptlib.py  by Ambrosa http://www.ambrosa.net
+# derived from E2_LOADEPG
+# 12-Jan-2011
+
+__author__ = "ambrosa http://www.ambrosa.net"
+__copyright__ = "Copyright (C) 2008-2011 Alessandro Ambrosini"
+__license__ = "CreativeCommons by-nc-sa http://creativecommons.org/licenses/by-nc-sa/3.0/"
+
+
+import os
+import sys
+import time
+import codecs
+import crossepg
+
+# escape some incorrect chars from filename
+def fn_escape(s):
+	if type(s).__name__ == 'str':
+		s = s.decode('utf-8')
+
+	s = s.replace(' ','_')
+	s = s.replace('/','_')
+	s = s.replace(':','_')
+	s = s.replace('.','_')
+	s = s.replace('|','_')
+	s = s.replace('!','_')
+
+	return(s.encode('utf-8'))
+
+# logging class
+class logging_class:
+
+	def __init__(self):
+		# get where CrossEPG save data (dbroot) and use it for opening crossepg.log
+		dbroot = crossepg.epgdb_get_dbroot()
+		if dbroot == True:
+			crossepg.log_open(dbroot)
+
+	def log(self,s):
+		crossepg.log_add(str(s))
+
+	def log2video_status(self,s):
+		print("LOGTEXT " + str(s))
+
+	def log2video_scriptname(self,s):
+		print("TYPE RUNNING CSCRIPT " + str(s))
+
+
+
+# decompress gzipped data
+class zlib_class:
+	GZTMP_FILE = "gunzip_temp.gz"
+	UNGZTMP_FILE = "gunzip_temp"
+	BIN_GZUNZIP = "gunzip -c " + GZTMP_FILE
+
+	def gzuncompress(self,data):
+		fd = open(self.GZTMP_FILE,'w')
+		fd.write(data)
+		fd.close()
+
+		fd = os.popen(self.BIN_GZUNZIP)
+		data_ungz = fd.read()
+		fd.close()
+		os.unlink(self.GZTMP_FILE)
+		return(data_ungz)
+
+
+# removing old cached epg files **
+def cleanup_oldcachedfiles(cachedir, field_separator):
+	TODAY = time.strftime("%Y%m%d")
+
+	for cachedfile in os.listdir(cachedir):
+		# extract date from filename
+		if cachedfile.split(field_separator)[-1] < TODAY :
+			os.unlink(os.path.join(cachedir,cachedfile))
+
+
+# return LOCALTIME - GMTIME (with DST)
+# return negative number if timezone is east of GMT (like Italy)
+# return postive number if timezone is west of GMT (like USA)
+def delta_utc():
+	if time.localtime().tm_isdst == 0 :
+		# return localtime - gmtime (in seconds)
+		return time.timezone
+	else:
+		# return (localtime - gmtime - DST)
+		return time.altzone
+
+
+# return DST time difference (in seconds)
+def delta_dst():
+	if time.localtime().tm_isdst == 0 :
+		return 0
+	else:
+		# return DST difference
+		return abs(time.altzone - time.timezone)
+
+
+# manage channel list from lamedb
+class lamedb_class:
+
+	LAMEDB='/etc/enigma2/lamedb'
+
+	# initialize an empty dictionary (Python array) indexed by channel name
+	# format: { channel_name : [ (sid , provider) , (sid , provider) , .... ] }
+	INDEXBYCHNAME = True
+	lamedb_dict = {}
+
+	# lamedb indexed by provider name
+	# format: { provider_name : [ (sid , channel_name) , (sid , channel_name) , .... ] }
+	INDEXBYPROVID = False # if True, also create the array lamedb_dict_prov, usually false for saving memory
+	lamedb_provid_dict = {}
+
+	def __init__(self, index_by_chname = True, index_by_provid = False):
+		self.INDEXBYCHNAME = index_by_chname
+		self.INDEXBYPROVID = index_by_provid
+		self.read_lamedb()
+
+	# first of all try to decode a string using UTF-8, if it fails then try with ISO-8859-1
+	# always return an Unicode string
+	def decode_charset(self,s):
+		u = None
+		charset_list = ('utf-8','iso-8859-1','iso-8859-2','iso-8859-15')
+
+		for charset in charset_list:
+			try:
+				u = unicode(s,charset,"strict")
+			except:
+				pass
+			else:
+				break
+
+		if u == None:
+			print("CHARSET ERROR while decoding lamedb")
+			sys.exit(1)
+		else:
+			return(u)
+
+
+	def read_lamedb(self):
+		if not os.path.exists(self.LAMEDB):
+			print("ERROR ! \'%s\' NOT FOUND" % self.LAMEDB)
+			sys.exit(1)
+
+		# lamedb mix UTF-8 + iso-8859-* inside it
+		# need charset decoding line by line
+		fd = open(self.LAMEDB,"r")
+
+		# skip transponder section
+		# read lamedb until are found "end" and "services" lines
+		while True:
+			temp = self.decode_charset(fd.readline())
+			if temp == '' :
+				print("ERROR parsing lamedb, transponder section: end of file")
+				sys.exit(1)
+
+			temp = temp.strip(' \n\r')
+			if temp == u"end":
+				# next line should be "services"
+				temp = self.decode_charset(fd.readline())
+				temp = temp.strip(' \n\r')
+				if temp == u'services':
+					# reached end of transponder section, end loop and continue with parsing channel section
+					break
+				else:
+					print("ERROR parsing lamedb, transponder section: not found \"end + services\" lines")
+					sys.exit(1)
+
+		# parsing lamedb channel section
+		while True:
+			sid = self.decode_charset(fd.readline()) # read SID , it's the first line
+
+			if sid == '' :
+				print("ERROR parsing lamedb, channel_name section: end of file")
+				sys.exit(1)
+
+			sid = sid.strip(' \n\r')
+
+			if sid == u'end':
+				# reached end of channel section, end loop
+				break;
+
+			channel_name = self.decode_charset(fd.readline()) # read channel name, this is the second line
+
+			channel_name = channel_name.strip(' \n\r').lower() # force channel name lowercase
+
+			temp = self.decode_charset(fd.readline()) # read provider , this is the third line
+			temp = temp.strip(' \n\r').lower()
+
+			temp_P = temp.find('p:')
+			if temp_P == -1 :
+				print("ERROR parsing lamedb, channel_name section: provider name \'p:\' not present")
+				sys.exit(1)
+			else:
+				temp = temp[(temp_P + 2):]
+				temp = temp.split(',')[0]
+				temp = temp.strip(' \n\r')
+				if temp == '':
+					provider_name = u'noprovider'
+				else:
+					provider_name = temp.lower()
+
+			#channel_name=channel_name.encode('utf-8')
+			#provider_name=provider_name.encode('utf-8')
+
+			if self.INDEXBYCHNAME == True:
+				sp = (sid,provider_name)
+				if channel_name != '':
+					if self.lamedb_dict.has_key(channel_name):
+						self.lamedb_dict[channel_name].append(sp)
+					else:
+						self.lamedb_dict[channel_name]=[sp]
+
+			if self.INDEXBYPROVID == True:
+				sp = (sid,channel_name)
+				if self.lamedb_provid_dict.has_key(provider_name):
+					self.lamedb_provid_dict[provider_name].append(sp)
+				else:
+					self.lamedb_provid_dict[provider_name]=[sp]
+
+				
+
+		fd.close()
+
+		if len(self.lamedb_dict) == 0 :
+			print("ERROR lamedb empty ?")
+			sys.exit(1)
+
+
+	def get_sid_byname(self,channel_name):
+		sid_list = []
+
+		if self.lamedb_dict.has_key(channel_name) :
+			for v in self.lamedb_dict[channel_name]:
+				# (sid,provider_name)
+				sid_list.append(v[0])
+
+		return(sid_list)
+
+
+	def get_provid_byname(self,channel_name):
+		provid_list = []
+
+		if self.lamedb_dict.has_key(channel_name) :
+			for v in self.lamedb_dict[channel_name]:
+				# (sid,provider_name)
+				provid_list.append(v[1])
+
+		return(provid_list)
+
+	def get_sidprovid_byname(self,channel_name):
+		sidprov_list = []
+		if self.lamedb_dict.has_key(channel_name) :
+			# (sid,provider_name)
+			sidprov_list = self.lamedb_dict[channel_name]
+
+		return(sidprov_list)
+
+
+	def get_chnames_byprov(self,provider_name):
+		if self.INDEXBYPROVID == True:
+			if self.lamedb_provid_dict.has_key(provider_name) :
+				return self.lamedb_provid_dict[provider_name]
+			else:
+				return None
+		return None
+
+	def convert_sid(self,sid):
+		s=[]
+
+		# SID:ns:TSID:ONID:stype:unused
+
+		try:
+			tmp = sid.split(":")
+			s.append(int(tmp[0],0x10))  # SID
+			s.append(int(tmp[2],0X10))  # TSID
+			s.append(int(tmp[3],0X10))  # ONID
+		except:
+			pass
+
+		return(s)
+
+
+class crossepg_db_class:
+
+	db_channel_ref = ''
+	event_id = 1
+
+	title_ref = ''
+
+	def __init__(self):
+		pass
+
+	def open_db(self):
+		# get where CrossEPG save data (dbroot)
+		dbroot = crossepg.epgdb_get_dbroot()
+		# open CrossEPG database
+		if not crossepg.epgdb_open(dbroot):
+			print("ERROR opening CrossEPG database")
+			sys.exit(1)
+
+		# load database structures (index, ....)
+		crossepg.epgdb_load()
+
+	def close_db(self):
+		# save data
+		if crossepg.epgdb_save(None):
+			print("CrossEPG data saved")
+		else:
+			print("CrossEPG Error saving data")
+
+		# close epgdb and clean memory
+		crossepg.epgdb_close()
+		crossepg.epgdb_clean()
+
+
+	# add channel into db and get a reference to the structure
+	# doesn't matter if the channel already exist... epgdb do all the work
+	def add_channel(self,ch_sid):
+		# epgdb_channels_add(onid, tsid, sid)
+		self.db_channel_ref = crossepg.epgdb_channels_add(ch_sid[2], ch_sid[1], ch_sid[0])
+		self.event_id = 1
+
+	# add an EPG event
+	def add_event(self, start_time, duration, title=' ', summarie=' ', language='eng', utf8=False):
+		start_time = int(start_time)
+		duration = int(duration)
+
+		if (duration < 0) or (duration > 65535) :
+			# duration must be >= 0 or < 65536 , skip this event (it's an error)
+			print("DEBUG: length error %d" % duration)
+			return
+
+		event_ref = crossepg.epgdb_title_alloc() # alloc title structure in memory		
+		event_ref.event_id = self.event_id  # event_id is unique inside a channel
+		self.event_id += 1
+
+		event_ref.start_time = start_time	# Unix timestamp, always referred to gmt+0 without daylight saving
+		event_ref.mjd = crossepg.epgdb_calculate_mjd(event_ref.start_time)	# Modified Julian Date. if you don't know it you can calulate it with epgdb_calculate_mjd()
+	
+		# print("       title %s , starttime %s , duration %f" % (title, start_time, duration))
+		event_ref.length = duration  # event duration in seconds
+
+		# ISO 639 language code. http://en.wikipedia.org/wiki/ISO_639
+		event_ref.iso_639_1 = ord(language[0:1])
+		event_ref.iso_639_2 = ord(language[1:2])
+		event_ref.iso_639_3 = ord(language[2:3])
+
+		# add event in epgdb and return back a reference to the structure
+		# remember to use always the new structure reference
+		# if the event already exist epgdb update it and automatically destroy the new structure
+		event_ref = crossepg.epgdb_titles_add(self.db_channel_ref, event_ref)
+
+
+		#print("DEBUG , title DATA TYPE: \'%s\'" % type(title).__name__ )
+		#print("DEBUG , summarie DATA TYPE: \'%s\'" % type(summarie).__name__ )
+
+		if utf8 == False :
+			crossepg.epgdb_titles_set_description(event_ref, title);
+			crossepg.epgdb_titles_set_long_description(event_ref, summarie);
+		else:
+			crossepg.epgdb_titles_set_description_utf8(event_ref, title);
+			crossepg.epgdb_titles_set_long_description_utf8(event_ref, summarie);
+
+
Index: ipk/source/epg_crossepg_0_61/var/crossepg/scripts/lib/sgmllib.py
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/scripts/lib/sgmllib.py	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/scripts/lib/sgmllib.py	(revision 6505)
@@ -0,0 +1,548 @@
+"""A parser for SGML, using the derived class as a static DTD."""
+
+# XXX This only supports those SGML features used by HTML.
+
+# XXX There should be a way to distinguish between PCDATA (parsed
+# character data -- the normal case), RCDATA (replaceable character
+# data -- only char and entity references and end tags are special)
+# and CDATA (character data -- only end tags are special).  RCDATA is
+# not supported at all.
+
+
+import markupbase
+import re
+
+__all__ = ["SGMLParser", "SGMLParseError"]
+
+# Regular expressions used for parsing
+
+interesting = re.compile('[&<]')
+incomplete = re.compile('&([a-zA-Z][a-zA-Z0-9]*|#[0-9]*)?|'
+                           '<([a-zA-Z][^<>]*|'
+                              '/([a-zA-Z][^<>]*)?|'
+                              '![^<>]*)?')
+
+entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')
+charref = re.compile('&#([0-9]+)[^0-9]')
+
+starttagopen = re.compile('<[>a-zA-Z]')
+shorttagopen = re.compile('<[a-zA-Z][-.a-zA-Z0-9]*/')
+shorttag = re.compile('<([a-zA-Z][-.a-zA-Z0-9]*)/([^/]*)/')
+piclose = re.compile('>')
+endbracket = re.compile('[<>]')
+tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*')
+attrfind = re.compile(
+    r'\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\s*=\s*'
+    r'(\'[^\']*\'|"[^"]*"|[][\-a-zA-Z0-9./,:;+*%?!&$\(\)_#=~\'"@]*))?')
+
+
+class SGMLParseError(RuntimeError):
+    """Exception raised for all parse errors."""
+    pass
+
+
+# SGML parser base class -- find tags and call handler functions.
+# Usage: p = SGMLParser(); p.feed(data); ...; p.close().
+# The dtd is defined by deriving a class which defines methods
+# with special names to handle tags: start_foo and end_foo to handle
+# <foo> and </foo>, respectively, or do_foo to handle <foo> by itself.
+# (Tags are converted to lower case for this purpose.)  The data
+# between tags is passed to the parser by calling self.handle_data()
+# with some data as argument (the data may be split up in arbitrary
+# chunks).  Entity references are passed by calling
+# self.handle_entityref() with the entity reference as argument.
+
+class SGMLParser(markupbase.ParserBase):
+    # Definition of entities -- derived classes may override
+    entity_or_charref = re.compile('&(?:'
+      '([a-zA-Z][-.a-zA-Z0-9]*)|#([0-9]+)'
+      ')(;?)')
+
+    def __init__(self, verbose=0):
+        """Initialize and reset this instance."""
+        self.verbose = verbose
+        self.reset()
+
+    def reset(self):
+        """Reset this instance. Loses all unprocessed data."""
+        self.__starttag_text = None
+        self.rawdata = ''
+        self.stack = []
+        self.lasttag = '???'
+        self.nomoretags = 0
+        self.literal = 0
+        markupbase.ParserBase.reset(self)
+
+    def setnomoretags(self):
+        """Enter literal mode (CDATA) till EOF.
+
+        Intended for derived classes only.
+        """
+        self.nomoretags = self.literal = 1
+
+    def setliteral(self, *args):
+        """Enter literal mode (CDATA).
+
+        Intended for derived classes only.
+        """
+        self.literal = 1
+
+    def feed(self, data):
+        """Feed some data to the parser.
+
+        Call this as often as you want, with as little or as much text
+        as you want (may include '\n').  (This just saves the text,
+        all the processing is done by goahead().)
+        """
+
+        self.rawdata = self.rawdata + data
+        self.goahead(0)
+
+    def close(self):
+        """Handle the remaining data."""
+        self.goahead(1)
+
+    def error(self, message):
+        raise SGMLParseError(message)
+
+    # Internal -- handle data as far as reasonable.  May leave state
+    # and data to be processed by a subsequent call.  If 'end' is
+    # true, force handling all data as if followed by EOF marker.
+    def goahead(self, end):
+        rawdata = self.rawdata
+        i = 0
+        n = len(rawdata)
+        while i < n:
+            if self.nomoretags:
+                self.handle_data(rawdata[i:n])
+                i = n
+                break
+            match = interesting.search(rawdata, i)
+            if match: j = match.start()
+            else: j = n
+            if i < j:
+                self.handle_data(rawdata[i:j])
+            i = j
+            if i == n: break
+            if rawdata[i] == '<':
+                if starttagopen.match(rawdata, i):
+                    if self.literal:
+                        self.handle_data(rawdata[i])
+                        i = i+1
+                        continue
+                    k = self.parse_starttag(i)
+                    if k < 0: break
+                    i = k
+                    continue
+                if rawdata.startswith("</", i):
+                    k = self.parse_endtag(i)
+                    if k < 0: break
+                    i = k
+                    self.literal = 0
+                    continue
+                if self.literal:
+                    if n > (i + 1):
+                        self.handle_data("<")
+                        i = i+1
+                    else:
+                        # incomplete
+                        break
+                    continue
+                if rawdata.startswith("<!--", i):
+                        # Strictly speaking, a comment is --.*--
+                        # within a declaration tag <!...>.
+                        # This should be removed,
+                        # and comments handled only in parse_declaration.
+                    k = self.parse_comment(i)
+                    if k < 0: break
+                    i = k
+                    continue
+                if rawdata.startswith("<?", i):
+                    k = self.parse_pi(i)
+                    if k < 0: break
+                    i = i+k
+                    continue
+                if rawdata.startswith("<!", i):
+                    # This is some sort of declaration; in "HTML as
+                    # deployed," this should only be the document type
+                    # declaration ("<!DOCTYPE html...>").
+                    k = self.parse_declaration(i)
+                    if k < 0: break
+                    i = k
+                    continue
+            elif rawdata[i] == '&':
+                if self.literal:
+                    self.handle_data(rawdata[i])
+                    i = i+1
+                    continue
+                match = charref.match(rawdata, i)
+                if match:
+                    name = match.group(1)
+                    self.handle_charref(name)
+                    i = match.end(0)
+                    if rawdata[i-1] != ';': i = i-1
+                    continue
+                match = entityref.match(rawdata, i)
+                if match:
+                    name = match.group(1)
+                    self.handle_entityref(name)
+                    i = match.end(0)
+                    if rawdata[i-1] != ';': i = i-1
+                    continue
+            else:
+                self.error('neither < nor & ??')
+            # We get here only if incomplete matches but
+            # nothing else
+            match = incomplete.match(rawdata, i)
+            if not match:
+                self.handle_data(rawdata[i])
+                i = i+1
+                continue
+            j = match.end(0)
+            if j == n:
+                break # Really incomplete
+            self.handle_data(rawdata[i:j])
+            i = j
+        # end while
+        if end and i < n:
+            self.handle_data(rawdata[i:n])
+            i = n
+        self.rawdata = rawdata[i:]
+        # XXX if end: check for empty stack
+
+    # Extensions for the DOCTYPE scanner:
+    _decl_otherchars = '='
+
+    # Internal -- parse processing instr, return length or -1 if not terminated
+    def parse_pi(self, i):
+        rawdata = self.rawdata
+        if rawdata[i:i+2] != '<?':
+            self.error('unexpected call to parse_pi()')
+        match = piclose.search(rawdata, i+2)
+        if not match:
+            return -1
+        j = match.start(0)
+        self.handle_pi(rawdata[i+2: j])
+        j = match.end(0)
+        return j-i
+
+    def get_starttag_text(self):
+        return self.__starttag_text
+
+    # Internal -- handle starttag, return length or -1 if not terminated
+    def parse_starttag(self, i):
+        self.__starttag_text = None
+        start_pos = i
+        rawdata = self.rawdata
+        if shorttagopen.match(rawdata, i):
+            # SGML shorthand: <tag/data/ == <tag>data</tag>
+            # XXX Can data contain &... (entity or char refs)?
+            # XXX Can data contain < or > (tag characters)?
+            # XXX Can there be whitespace before the first /?
+            match = shorttag.match(rawdata, i)
+            if not match:
+                return -1
+            tag, data = match.group(1, 2)
+            self.__starttag_text = '<%s/' % tag
+            tag = tag.lower()
+            k = match.end(0)
+            self.finish_shorttag(tag, data)
+            self.__starttag_text = rawdata[start_pos:match.end(1) + 1]
+            return k
+        # XXX The following should skip matching quotes (' or ")
+        # As a shortcut way to exit, this isn't so bad, but shouldn't
+        # be used to locate the actual end of the start tag since the
+        # < or > characters may be embedded in an attribute value.
+        match = endbracket.search(rawdata, i+1)
+        if not match:
+            return -1
+        j = match.start(0)
+        # Now parse the data between i+1 and j into a tag and attrs
+        attrs = []
+        if rawdata[i:i+2] == '<>':
+            # SGML shorthand: <> == <last open tag seen>
+            k = j
+            tag = self.lasttag
+        else:
+            match = tagfind.match(rawdata, i+1)
+            if not match:
+                self.error('unexpected call to parse_starttag')
+            k = match.end(0)
+            tag = rawdata[i+1:k].lower()
+            self.lasttag = tag
+        while k < j:
+            match = attrfind.match(rawdata, k)
+            if not match: break
+            attrname, rest, attrvalue = match.group(1, 2, 3)
+            if not rest:
+                attrvalue = attrname
+            else:
+                if (attrvalue[:1] == "'" == attrvalue[-1:] or
+                    attrvalue[:1] == '"' == attrvalue[-1:]):
+                    # strip quotes
+                    attrvalue = attrvalue[1:-1]
+                attrvalue = self.entity_or_charref.sub(
+                    self._convert_ref, attrvalue)
+            attrs.append((attrname.lower(), attrvalue))
+            k = match.end(0)
+        if rawdata[j] == '>':
+            j = j+1
+        self.__starttag_text = rawdata[start_pos:j]
+        self.finish_starttag(tag, attrs)
+        return j
+
+    # Internal -- convert entity or character reference
+    def _convert_ref(self, match):
+        if match.group(2):
+            return self.convert_charref(match.group(2)) or \
+                '&#%s%s' % match.groups()[1:]
+        elif match.group(3):
+            return self.convert_entityref(match.group(1)) or \
+                '&%s;' % match.group(1)
+        else:
+            return '&%s' % match.group(1)
+
+    # Internal -- parse endtag
+    def parse_endtag(self, i):
+        rawdata = self.rawdata
+        match = endbracket.search(rawdata, i+1)
+        if not match:
+            return -1
+        j = match.start(0)
+        tag = rawdata[i+2:j].strip().lower()
+        if rawdata[j] == '>':
+            j = j+1
+        self.finish_endtag(tag)
+        return j
+
+    # Internal -- finish parsing of <tag/data/ (same as <tag>data</tag>)
+    def finish_shorttag(self, tag, data):
+        self.finish_starttag(tag, [])
+        self.handle_data(data)
+        self.finish_endtag(tag)
+
+    # Internal -- finish processing of start tag
+    # Return -1 for unknown tag, 0 for open-only tag, 1 for balanced tag
+    def finish_starttag(self, tag, attrs):
+        try:
+            method = getattr(self, 'start_' + tag)
+        except AttributeError:
+            try:
+                method = getattr(self, 'do_' + tag)
+            except AttributeError:
+                self.unknown_starttag(tag, attrs)
+                return -1
+            else:
+                self.handle_starttag(tag, method, attrs)
+                return 0
+        else:
+            self.stack.append(tag)
+            self.handle_starttag(tag, method, attrs)
+            return 1
+
+    # Internal -- finish processing of end tag
+    def finish_endtag(self, tag):
+        if not tag:
+            found = len(self.stack) - 1
+            if found < 0:
+                self.unknown_endtag(tag)
+                return
+        else:
+            if tag not in self.stack:
+                try:
+                    method = getattr(self, 'end_' + tag)
+                except AttributeError:
+                    self.unknown_endtag(tag)
+                else:
+                    self.report_unbalanced(tag)
+                return
+            found = len(self.stack)
+            for i in range(found):
+                if self.stack[i] == tag: found = i
+        while len(self.stack) > found:
+            tag = self.stack[-1]
+            try:
+                method = getattr(self, 'end_' + tag)
+            except AttributeError:
+                method = None
+            if method:
+                self.handle_endtag(tag, method)
+            else:
+                self.unknown_endtag(tag)
+            del self.stack[-1]
+
+    # Overridable -- handle start tag
+    def handle_starttag(self, tag, method, attrs):
+        method(attrs)
+
+    # Overridable -- handle end tag
+    def handle_endtag(self, tag, method):
+        method()
+
+    # Example -- report an unbalanced </...> tag.
+    def report_unbalanced(self, tag):
+        if self.verbose:
+            print '*** Unbalanced </' + tag + '>'
+            print '*** Stack:', self.stack
+
+    def convert_charref(self, name):
+        """Convert character reference, may be overridden."""
+        try:
+            n = int(name)
+        except ValueError:
+            return
+        if not 0 <= n <= 255:
+            return
+        return self.convert_codepoint(n)
+
+    def convert_codepoint(self, codepoint):
+        return chr(codepoint)
+
+    def handle_charref(self, name):
+        """Handle character reference, no need to override."""
+        replacement = self.convert_charref(name)
+        if replacement is None:
+            self.unknown_charref(name)
+        else:
+            self.handle_data(replacement)
+
+    # Definition of entities -- derived classes may override
+    entitydefs = \
+            {'lt': '<', 'gt': '>', 'amp': '&', 'quot': '"', 'apos': '\''}
+
+    def convert_entityref(self, name):
+        """Convert entity references.
+
+        As an alternative to overriding this method; one can tailor the
+        results by setting up the self.entitydefs mapping appropriately.
+        """
+        table = self.entitydefs
+        if name in table:
+            return table[name]
+        else:
+            return
+
+    def handle_entityref(self, name):
+        """Handle entity references, no need to override."""
+        replacement = self.convert_entityref(name)
+        if replacement is None:
+            self.unknown_entityref(name)
+        else:
+            self.handle_data(self.convert_entityref(name))
+
+    # Example -- handle data, should be overridden
+    def handle_data(self, data):
+        pass
+
+    # Example -- handle comment, could be overridden
+    def handle_comment(self, data):
+        pass
+
+    # Example -- handle declaration, could be overridden
+    def handle_decl(self, decl):
+        pass
+
+    # Example -- handle processing instruction, could be overridden
+    def handle_pi(self, data):
+        pass
+
+    # To be overridden -- handlers for unknown objects
+    def unknown_starttag(self, tag, attrs): pass
+    def unknown_endtag(self, tag): pass
+    def unknown_charref(self, ref): pass
+    def unknown_entityref(self, ref): pass
+
+
+class TestSGMLParser(SGMLParser):
+
+    def __init__(self, verbose=0):
+        self.testdata = ""
+        SGMLParser.__init__(self, verbose)
+
+    def handle_data(self, data):
+        self.testdata = self.testdata + data
+        if len(repr(self.testdata)) >= 70:
+            self.flush()
+
+    def flush(self):
+        data = self.testdata
+        if data:
+            self.testdata = ""
+            print 'data:', repr(data)
+
+    def handle_comment(self, data):
+        self.flush()
+        r = repr(data)
+        if len(r) > 68:
+            r = r[:32] + '...' + r[-32:]
+        print 'comment:', r
+
+    def unknown_starttag(self, tag, attrs):
+        self.flush()
+        if not attrs:
+            print 'start tag: <' + tag + '>'
+        else:
+            print 'start tag: <' + tag,
+            for name, value in attrs:
+                print name + '=' + '"' + value + '"',
+            print '>'
+
+    def unknown_endtag(self, tag):
+        self.flush()
+        print 'end tag: </' + tag + '>'
+
+    def unknown_entityref(self, ref):
+        self.flush()
+        print '*** unknown entity ref: &' + ref + ';'
+
+    def unknown_charref(self, ref):
+        self.flush()
+        print '*** unknown char ref: &#' + ref + ';'
+
+    def unknown_decl(self, data):
+        self.flush()
+        print '*** unknown decl: [' + data + ']'
+
+    def close(self):
+        SGMLParser.close(self)
+        self.flush()
+
+
+def test(args = None):
+    import sys
+
+    if args is None:
+        args = sys.argv[1:]
+
+    if args and args[0] == '-s':
+        args = args[1:]
+        klass = SGMLParser
+    else:
+        klass = TestSGMLParser
+
+    if args:
+        file = args[0]
+    else:
+        file = 'test.html'
+
+    if file == '-':
+        f = sys.stdin
+    else:
+        try:
+            f = open(file, 'r')
+        except IOError, msg:
+            print file, ":", msg
+            sys.exit(1)
+
+    data = f.read()
+    if f is not sys.stdin:
+        f.close()
+
+    x = klass()
+    for c in data:
+        x.feed(c)
+    x.close()
+
+
+if __name__ == '__main__':
+    test()
Index: ipk/source/epg_crossepg_0_61/var/crossepg/scripts/lib/webif.py
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/scripts/lib/webif.py	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/scripts/lib/webif.py	(revision 6505)
@@ -0,0 +1,126 @@
+#!/usr/bin/python
+
+# webif.py  by Ambrosa http://www.ambrosa.net
+# this module is used for manage Web Interface
+# not tested with CrossEPG
+
+__author__ = "ambrosa http://www.ambrosa.net"
+__version__ = "0.53 beta E2_LOADEPG"
+__copyright__ = "Copyright (C) 2008-2009 Alessandro Ambrosini"
+__license__ = "CreativeCommons by-nc-sa http://creativecommons.org/licenses/by-nc-sa/3.0/"
+
+import time
+import string
+import urllib2
+from urllib import quote_plus
+from xml.dom import minidom
+
+
+class webif_class:
+    USE_WEBIF=1
+    USE_WEBIF_AUTH=0
+    WEBIF_AUTH_USER='root'
+    WEBIF_AUTH_PASSW='qboxhd'
+    WEBIF_AUTH_REALM='dm7025'
+    WEBIF_IP='127.0.0.1'
+    
+    def __init__(self,use,auth,auth_name,auth_passw,auth_realm,ip):
+        self.USE_WEBIF=use
+        self.USE_WEBIF_AUTH=auth
+        self.WEBIF_AUTH_USER=auth_name
+        self.WEBIF_AUTH_PASSW=auth_passw
+        self.WEBIF_AUTH_REALM=auth_realm
+        self.WEBIF_IP=ip
+
+
+    def get_use_webif(self):
+        return(self.USE_WEBIF)
+        
+        
+    # WebInterface routines
+    # see http://dream.reichholf.net/wiki/Enigma2:WebInterface    
+    def WI(self,command):   
+        
+        if self.USE_WEBIF_AUTH == 1 :    
+            auth_handler = urllib2.HTTPBasicAuthHandler()
+            auth_handler.add_password(self.WEBIF_AUTH_REALM, 'http://' + self.WEBIF_IP, self.WEBIF_AUTH_USER, self.WEBIF_AUTH_PASSW)
+            opener = urllib2.build_opener(auth_handler)
+            urllib2.install_opener(opener)
+            
+        try:
+            sock=urllib2.urlopen('http://' + self.WEBIF_IP + '/web/' + command)
+            data=sock.read()
+        except urllib2.URLError:
+            pass
+        except urllib2.HTTPError:
+            pass
+        except urllib2.httplib.BadStatusLine:
+            pass
+        else:
+            sock.close()
+            return(data)
+            
+    def standby(self):
+        current_sid=self.currentchannelsid()
+        if current_sid != None:
+            self.WI('powerstate?newstate=0')
+            time.sleep(5)
+        
+    def restartenigma(self):
+        self.WI('powerstate?newstate=3')
+        
+    def switchon(self):
+        current_sid=self.currentchannelsid()
+        if current_sid == None:
+            # DM appears switched off. Switch it on !
+        
+            # switch on emulating remote keypress
+            # 'powerstate?newstate=116' is not (?) working
+            #self.WI('remotecontrol?command=116')       
+            self.WI('powerstate?newstate=0')
+
+            time.sleep(5)
+            current_sid=self.currentchannelsid()
+        
+        return(current_sid)
+
+
+    def zap(self,channelsid):
+        self.WI('zap?sRef='+channelsid)
+
+    def reloadepgdat(self):
+        self.WI('powerstate?newstate=10')
+
+    def currentchannelsid(self):
+        # DM must be SWITCHED ON
+        # if DM is in standby mode, it return 'none'
+        data=self.WI('subservices')
+        
+        if data == None :
+            return(None)
+            
+        try:
+            xmldoc = minidom.parseString(data)
+        except:
+            return(None)
+        
+        r=xmldoc.getElementsByTagName('e2servicereference')[0].firstChild.data
+        if r == 'N/A':
+            return(None)
+            
+        return(r)
+
+    def is_recording(self):
+        data=self.WI("timerlist")
+        if data.find("<e2state>2</e2state>") == -1:
+            return(False) # not recording
+        else:
+            return(True) # recording
+
+    def message(self,txt,timeout=10,type=1):
+        is_on=self.currentchannelsid()
+        # WARNING: if DM is switched off, sending a message cause a lock/crash in the system
+        if is_on != None:
+            self.WI("message?text="+quote_plus("E2_LOADEPG - "+txt)+"&type="+str(type)+"&timeout="+str(timeout))
+        
+
Index: ipk/source/epg_crossepg_0_61/var/crossepg/scripts/mediaprem/example-mediaprem-minidom.py
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/scripts/mediaprem/example-mediaprem-minidom.py	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/scripts/mediaprem/example-mediaprem-minidom.py	(revision 6505)
@@ -0,0 +1,557 @@
+#!/usr/bin/python
+# mediaprem.py  by Ambrosa http://www.ambrosa.net
+# this module is used for download EPG data from Mediaset website
+# derived from E2_LOADEPG
+
+__author__ = "ambrosa http://www.ambrosa.net"
+__copyright__ = "Copyright (C) 2008-2011 Alessandro Ambrosini"
+__license__ = "CreativeCommons by-nc-sa http://creativecommons.org/licenses/by-nc-sa/3.0/"
+
+import gc
+import os
+import sys
+import time
+import codecs
+import socket
+import urllib
+import urllib2
+import ConfigParser
+from xml.dom import minidom
+
+# import CrossEPG functions
+import crossepg
+
+# location of local python modules under "scripts/lib" dir.
+# add it to sys.path()
+crossepg_instroot = crossepg.epgdb_get_installroot()
+if crossepg_instroot == False:
+	sys.exit(1)
+libdir = os.path.join(crossepg_instroot , 'scripts/lib')
+sys.path.append(libdir)
+
+# import local modules
+import sgmllib
+import scriptlib
+
+# =================================================================
+# HTML PARSER
+
+
+class Description_parser(sgmllib.SGMLParser):
+	def parse(self, s):
+		self.feed(s)
+		self.close()
+
+	def __init__(self, verbose=0):
+		sgmllib.SGMLParser.__init__(self, verbose)
+		self.start_div_box = False
+		self.start_div_boxtxt = False
+		self.description = ''
+
+
+	def start_div(self, attributes):
+		for name, value in attributes:
+			if name == "class":
+				if value == "box_Text":
+					self.start_div_box = True
+				elif value == "txtBox_cms":
+					self.start_div_boxtxt = True
+
+	def end_div(self):
+		if self.start_div_boxtxt == True:
+			self.start_div_box = False
+			self.start_div_boxtxt = False
+
+
+	def handle_data(self, data):
+		if self.start_div_boxtxt == True:
+			self.description += data.decode('iso-8859-1')
+
+	def get_descr(self):
+		return (self.description.strip(' \n\r') )
+
+# =================================================================
+
+
+class main:
+
+	# main config file
+	CONF_CONFIGFILENAME = "mediaprem.conf"
+
+	# Network socket timeout (in seconds)
+	CONF_SOCKET_TIMEOUT = 20
+
+	# log text
+	CONF_LOG_SCRIPT_NAME = "MediasetPremium (Italy)"
+	CONF_LOG_PREFIX = ""
+
+	# max chars in description
+	CONF_DLDESCMAXCHAR = 250
+
+	# retry number if HTTP error
+	HTTP_ERROR_RETRY = 3
+	# seconds to wait between retries
+	HTTP_ERROR_WAIT_RETRY = 5
+
+	# charset used in remote website epg data
+	REMOTE_EPG_CHARSET = 'utf-8'
+
+	TODAYMP = ''
+	DAYCACHEMP = []
+	FIELD_SEPARATOR = '###'
+	CHANNELLIST = {}
+
+
+	def log(self,s,video=0):
+		self.logging.log(self.CONF_LOG_PREFIX + str(s))
+		if video == 1:
+			self.log2video(str(s))
+
+	def log2video(self,s):
+		self.logging.log2video_status(str(s))
+
+	def convert_daymp(self,dmp):
+		daystandard = time.strftime("%Y%m%d",time.strptime(dmp,"%Y/%m/%d"))
+		return daystandard
+
+
+	def get_description(self,url):
+
+		if url[:7] != 'http://':
+			return('')
+
+		if (url[-5:] != '.html') and (url[-4:] != '.htm') :
+			return('')
+
+		self.log("   downloading description \'" + url + "\'")
+		url = str(urllib.quote(url,safe=":/"))
+
+		try:
+			sock = urllib2.urlopen(url)
+			data = sock.read()
+		except IOError, e:
+			serr = "unknown"
+			if hasattr(e, 'reason'):
+				serr = str(e.reason)
+			elif hasattr(e, 'code'):
+				serr = str(e.code)
+				if hasattr(e, 'msg'):
+					serr += " , " + str(e.msg)
+
+			self.log(url + "      error, reason: " + serr + ". Skip it.")
+			return('')
+
+		else:
+			sock.close()
+			dsparser = Description_parser()
+			dsparser.parse(data)
+			return(dsparser.get_descr())
+
+		return('')
+
+
+
+	def __init__(self,confdir,dbroot):
+
+		# initialize logging
+		self.logging = scriptlib.logging_class()
+		# write to video OSD the script name
+		self.logging.log2video_scriptname(self.CONF_LOG_SCRIPT_NAME)
+
+
+		# check swap memory available
+		osp = os.popen('free | awk \'/Swap/ { print $2 }\'','r')
+		ret = osp.readlines()
+		if len(ret) > 0:
+			try:
+				m = int(ret[0])/1024
+			except:
+				self.log("Error get SWAP value, abort",1)
+				time.sleep(10)
+				sys.exit(1)
+
+			if m < 60:
+				self.log("SWAP Not Enabled (<60MB), abort",1)
+				time.sleep(10)
+				sys.exit(1)
+		else:
+			self.log("Error get SWAP value, abort",1)
+			time.sleep(10)
+			sys.exit(1)
+
+		osp.close()
+
+
+		CONF_FILE = os.path.join(confdir,self.CONF_CONFIGFILENAME)
+		if not os.path.exists(CONF_FILE) :
+			self.log("ERROR: %s not present" % CONF_FILE,1)
+			sys.exit(1)
+
+		config = ConfigParser.ConfigParser()
+		#config.optionxform = str  # needed to return case sensitive index
+		config.read(CONF_FILE)
+
+		# reading [global] section options
+		self.CONF_DEFAULT_PROVIDER = config.get("global","DEFAULT_PROVIDER")
+		# save cache under dbroot
+		self.CONF_CACHEDIR = os.path.join(dbroot,config.get("global","CACHE_DIRNAME"))
+
+		self.CONF_DL_DESC = config.getint("global","DL_DESC")
+		self.CONF_MAX_DAY_EPG = config.getint("global","MAX_DAY_EPG")
+		self.CONF_URL = config.get("global","URL")
+
+		self.CONF_GMT_ZONE = config.get("global","GMT_ZONE")
+		if self.CONF_GMT_ZONE.strip(' ').lower() == 'equal':
+			#self.DELTA_UTC = -scriptlib.delta_utc() # return negative if timezone is east of GMT (like Italy), invert sign
+			self.DELTA_UTC = 0
+		else:
+			self.DELTA_UTC = float(self.CONF_GMT_ZONE)*3600.0
+			if self.DELTA_UTC >= 0:
+				self.DELTA_UTC = self.DELTA_UTC + scriptlib.delta_dst()
+			else:
+				self.DELTA_UTC = self.DELTA_UTC - scriptlib.delta_dst()
+
+		self.DELTA_UTC = int(self.DELTA_UTC)
+		#self.log("Website timezone - UTC = %d seconds" % self.DELTA_UTC)
+
+		if not os.path.exists(self.CONF_CACHEDIR):
+			self.log("Creating \'%s\' directory for caching" % self.CONF_CACHEDIR)
+			os.mkdir(self.CONF_CACHEDIR)
+
+		# reading [channels] section
+		temp = config.items("channels");
+
+		# create a dictionary (Python array) with index = channel ID
+		for i in temp:
+			self.CHANNELLIST[i[0].strip(' \n\r').lower()] = unicode(i[1].strip(' \n\r').lower(),'utf-8')
+
+		if len(self.CHANNELLIST) == 0 :
+			self.log("ERROR: [channels] section empty ?",1)
+			sys.exit(1)
+
+		# set network socket timeout
+		socket.setdefaulttimeout(self.CONF_SOCKET_TIMEOUT)
+
+		self.TODAYMP = time.strftime("%Y/%m/%d")
+		# create a list filled with dates (format AAAA/MM/DD) from today to today+ MAX_DAY_EPG
+		self.DAYCACHEMP=[self.TODAYMP]
+		for day in range(1,self.CONF_MAX_DAY_EPG):
+			self.DAYCACHEMP.append(time.strftime("%Y/%m/%d",time.localtime(time.time()+86400*day)))
+
+
+
+# ----------------------------------------------------------------------
+
+
+	def download_and_cache(self):
+		self.log("--- START DOWNLOAD AND CACHE DATA ---")
+		self.log2video("STARTING DOWNLOAD")
+
+		self.log("Removing old cached files")
+		scriptlib.cleanup_oldcachedfiles(self.CONF_CACHEDIR, self.FIELD_SEPARATOR)
+
+		chlist = self.CHANNELLIST
+
+		self.log("Start download XML data from \'" + self.CONF_URL+"\'")
+		self.log2video("downloading XML data ...")
+
+		i = self.HTTP_ERROR_RETRY
+		while i > 0:
+			try:
+				sock = urllib2.urlopen(self.CONF_URL)
+				data = sock.read()
+			except IOError, e:
+				serr = "unknown"
+				if hasattr(e, 'reason'):
+					serr = str(e.reason)
+				elif hasattr(e, 'code'):
+					serr = str(e.code)
+				if hasattr(e, 'msg'):
+					serr += " , " + str(e.msg)
+
+				self.log("\'" + self.CONF_URL + "\' connection error. Reason: "+serr+". Waiting "+str(self.HTTP_ERROR_WAIT_RETRY)+" sec. and retry ["+str(i)+"] ...")
+				time.sleep(self.HTTP_ERROR_WAIT_RETRY) # add sleep
+				i -= 1
+
+			else:
+				i = -99
+				sock.close()
+
+		if (i != -99):
+			self.log("Cannot retrieve data from \'" + self.CONF_URL + "\'. Abort script")
+			self.log2video("Error: cannot download XML data, abort")
+			time.sleep(5)
+			sys.exit(1)
+
+		self.log("End download XML data, now processing XML code.")
+		self.log2video("preprocessing XML data, wait ...")
+		try:
+			xmldoc = minidom.parseString(data)
+		except:
+			self.log("Warning ! Data are not in a valid XML format. Abort script")
+			self.log2video("Error: no valid XML data, abort")
+			time.sleep(5)
+			sys.exit(1)
+
+
+		self.log("End process XML data")
+		self.log2video("end process XML data")
+
+		# days list
+		xmlref_giorno = xmldoc.getElementsByTagName('giorno')
+		for xml_gg in xmlref_giorno:
+			gg = xml_gg.attributes["data"].value
+			if gg not in self.DAYCACHEMP :
+				continue
+
+			xmlref_canale = xml_gg.getElementsByTagName('canale')
+			for xml_ch in xmlref_canale:
+				chid = xml_ch.attributes["id"].value.strip(' \n\r').lower()
+				if not chlist.has_key(chid) :
+						self.log("Warning: new channel \"id=%s name=%s\" found in XML data" % (xml_ch.attributes["id"].value,xml_ch.attributes["description"]))
+						continue
+
+				clist = [chid]
+				if self.CHANNELLIST.has_key(chid + '+1'):
+					clist.append(chid + '+1')
+
+				for c in clist:
+
+					# get cache option
+					#  0 : don't download/cache
+					#  1 : download and cache (optional 1,new_name )
+					#  2 : always download overwriting existing files (optional 2,new_name )
+					#  3 : always download overwriting existing files only for TODAY (optional 3,new_name )
+
+					cacheopt = int(chlist[c].split(",")[0])
+
+					# if cacheopt == 0, do nothing
+					if cacheopt == 0:
+						continue
+
+					channel_name = ''
+					if len(chlist[c].split(",")) > 1 :
+						if chlist[c].split(",")[1] != '' :
+							# channel renamed, new name provided by user
+							channel_name = chlist[c].split(",")[1].strip(' \n\r').lower()
+
+					# if channel name is not present as option, quit with error
+					if channel_name == '':
+						self.log("ERROR ! ID=%s channel name not present" % c)
+						sys.exit(1)
+
+					channel_provider = self.CONF_DEFAULT_PROVIDER
+					if len(chlist[c].split(",")) > 2 :
+						if chlist[c].split(",")[2] != '' :
+							channel_provider = chlist[c].split(",")[2].strip(' \n\r').lower()
+
+					# if channel name is not present as option in channel_list.conf , quit with error
+					if channel_name == '':
+						self.log("ERROR ! ID=" + str(c) + " channel name not present. Skip !")
+						continue
+
+					# download only if file doesn't exist or cacheopt == 2 (always download),
+					# using open(...,"w") files will be overwritten (saving a delete + create)
+
+					day = str(self.convert_daymp(gg))
+					eventfilename = scriptlib.fn_escape(str(c) + self.FIELD_SEPARATOR + channel_name + self.FIELD_SEPARATOR + day)
+					eventfilepath = os.path.join(self.CONF_CACHEDIR, eventfilename)
+					if (cacheopt == 1) and os.path.exists(eventfilepath):
+						continue
+					if (cacheopt == 3) and os.path.exists(eventfilepath) and (gg != self.TODAYMP):
+						continue
+					if (cacheopt != 1) and (cacheopt != 2) and (cacheopt != 3):
+						self.log("Warning: unknown cache option " + str(cacheopt))
+						exit_for_loop = True
+						continue
+
+					num_events = 0
+					self.log("  Writing in cache \'" + eventfilename + "\'",2)
+					self.log2video(" extracting \"%s\" [%d] (%s)" % (channel_name, num_events, day))
+
+					fd=codecs.open(eventfilepath,"w",'utf-8')
+
+					fd.write(str(c) + self.FIELD_SEPARATOR + channel_name + self.FIELD_SEPARATOR + channel_provider + self.FIELD_SEPARATOR + day + '\n')
+					fd.write("Local Time (human readeable)###Unix GMT Time###Event Title###Event Description\n")
+
+					xmlref_events = xml_ch.getElementsByTagName('prg')
+					for xml_ee in xmlref_events:
+						orainiz = xml_ee.attributes["orainizio"].value
+
+						if (orainiz >='00:00') and (orainiz <= '05:59') :
+							nextdayevent = 86400
+						else:
+							nextdayevent = 0
+
+						event_starttime = gg + " " + orainiz
+
+						if c == (chid + '+1'):
+							# manage channel "+1"
+							event_startime_unix_gmt = str(int(time.mktime(time.strptime(event_starttime,"%Y/%m/%d %H:%M"))) - self.DELTA_UTC + 3600 + nextdayevent)
+						else:
+							# normal channel, not "+1"
+							event_startime_unix_gmt = str(int(time.mktime(time.strptime(event_starttime,"%Y/%m/%d %H:%M"))) - self.DELTA_UTC + nextdayevent)
+
+
+						event_title = unicode(xml_ee.getElementsByTagName('titolo')[0].firstChild.data)
+						event_title = event_title.replace('\r','')
+						event_title = event_title.replace('\n','')
+						event_title = event_title.strip(u' ')
+
+						event_description = ''
+						if self.CONF_DL_DESC == 1 :
+							url_desc = xml_ee.getElementsByTagName('linkScheda')[0].firstChild.data
+							event_description = unicode(self.get_description(url_desc.strip(' \n\r'))[:self.CONF_DLDESCMAXCHAR])
+							event_description = event_description.replace('\r','')
+							event_description = event_description.replace('\n',u' ')
+							event_description = event_description.strip(u' ')
+
+						fd.write(event_starttime + self.FIELD_SEPARATOR + event_startime_unix_gmt + self.FIELD_SEPARATOR + event_title + self.FIELD_SEPARATOR + event_description + '\n')
+						num_events += 1
+						self.log2video(" extracting \"%s\" [%d] (%s)" % (channel_name, num_events, day))
+
+
+					fd.close()
+
+		del xmldoc
+
+# ----------------------------------------------------------------------
+
+
+	def process_cache(self):
+		self.log("--- START PROCESSING CACHE ---")
+		self.log2video("START PROCESSING CACHE")
+		if not os.path.exists(self.CONF_CACHEDIR):
+			self.log("ERROR: %s not present" % self.CONF_CACHEDIR,1)
+			sys.exit(1)
+
+		self.log("Loading lamedb")
+		lamedb = scriptlib.lamedb_class()
+
+		self.log("Initialize CrossEPG database")
+		crossdb = scriptlib.crossepg_db_class()
+		crossdb.open_db()
+
+		events = []
+		previous_id = ''
+		channels_name = ''
+		total_events = 0
+
+		self.log("Start data processing")
+		filelist = sorted(os.listdir(self.CONF_CACHEDIR))
+		filelist.append('***END***')
+
+		for f in filelist :
+			id = f.split(self.FIELD_SEPARATOR)[0]
+			if previous_id == '':
+				previous_id = id
+
+			if id != previous_id :
+				total_events += len(events)
+				self.log("  ...processing \'%s\' , nr. events %d" % (previous_id,len(events)))
+				self.log2video("processed %d events ..." % total_events )
+
+				for c in channels_name:
+					# a channel can have zero or more SID (different channel with same name)
+					# return the list [0e1f:00820000:0708:00c8:1:0 , 1d20:00820000:2fa8:013e:1:0 , ..... ]
+					# return [] if channel name is not in lamedb
+					sidbyname = lamedb.get_sid_byname(c.strip(' \n').lower())
+
+					# process every SID
+					for s in sidbyname:
+						# convert "0e1f:00820000:0708:00c8:1:0" to sid,tsid,onid
+						# return the list [sid,tsid,onid]
+						ch_sid = lamedb.convert_sid(s)
+						if len(ch_sid) == 0:
+							continue
+
+						# add channel into db
+						# doesn't matter if the channel already exist... epgdb do all the work
+						crossdb.add_channel(ch_sid)
+
+						i = 0
+						L = len(events) - 1
+
+						# process events
+						for e in events:
+
+							items = e.split(self.FIELD_SEPARATOR)
+							e_starttime = int(items[1])
+
+							if i < L :
+								e_length = int(events[i+1].split(self.FIELD_SEPARATOR)[1]) - e_starttime
+							else:
+								# last event, dummy length 90 min.
+								e_length = 5400
+							i += 1
+
+							# extract title and encode Python Unicode with UTF-8
+							e_title = items[2].encode('utf-8')
+
+							# extract summarie and encode Python Unicode with UTF-8
+							e_summarie = items[3].encode('utf-8')
+
+							# add_event(start_time , duration , title , summarie , ISO639_language_code , strings_encoded_with_UTF-8)
+							crossdb.add_event(e_starttime, e_length, e_title, e_summarie, 'ita', True )
+
+				if f == '***END***':
+					break
+
+				events = []
+				previous_id = id
+				channels_name = ''
+
+			if id == previous_id:
+				self.log("Reading  \'%s\'" % f)
+				# read events from cache file using UTF-8 and insert them in events list
+				fd = codecs.open(os.path.join(self.CONF_CACHEDIR, f),"r","utf-8")
+				lines = fd.readlines()
+				fd.close()
+				if channels_name == '':
+					# first line has channel data (id,name,provider,date)
+					channels_name = lines[0].split(self.FIELD_SEPARATOR)[1].split('|')
+				# the second line is only a remark
+				# add events starting from third line
+				events.extend(lines[2:])
+
+		# end process, close CrossEPG DB saving data
+		crossdb.close_db()
+		self.log("TOTAL EPG EVENTS PROCESSED: %d" % total_events)
+		self.log("--- END ---")
+		self.log2video("END , events processed: %d" % total_events)
+
+
+
+# ****************************************************************************************************************************
+
+# MAIN CODE: SCRIPT START HERE
+
+# increase this process niceness (other processes have higher priority)
+os.nice(10)
+
+# set Garbage Collector to do a "generational jump" more frequently than default 700
+# memory saving: about 50% (!!), some performance loss (obviously)
+gc.set_threshold(50,10,10)
+
+SCRIPT_DIR = 'scripts/mediaprem/'
+
+# get CrossEPG installation dir.
+crossepg_instroot = crossepg.epgdb_get_installroot()
+if crossepg_instroot == False:
+	sys.exit(1)
+scriptlocation = os.path.join(crossepg_instroot , SCRIPT_DIR)
+
+# get where CrossEPG save data (dbroot) and use it as script cache repository
+crossepg_dbroot = crossepg.epgdb_get_dbroot()
+if crossepg_dbroot == False:
+	sys.exit(1)
+
+# initialize script class
+script_class = main(scriptlocation , crossepg_dbroot)
+
+# download data and cache them
+script_class.download_and_cache()
+
+# read cached data and inject into CrossEPG database
+script_class.process_cache()
+
Index: ipk/source/epg_crossepg_0_61/var/crossepg/scripts/mediaprem/mediaprem.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/scripts/mediaprem/mediaprem.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/scripts/mediaprem/mediaprem.conf	(revision 6505)
@@ -0,0 +1,124 @@
+# mediaprem.conf by ambrosa http://www.ambrosa.net
+# configuration file
+# 
+
+# ==================================================================================================
+# GLOBAL configuration section
+[global]
+
+# default provider used for searching channel name in lamedb
+DEFAULT_PROVIDER=mediaset
+
+# download event description (slow ! for every event it needs to download and parse e a web page)
+# DL_DESC=1 download description
+# DL_DESC=0 don't download description
+# default DL_DESC=1
+DL_DESC=1
+
+# cache dir name
+# default CACHE_DIRNAME=script_mediaprem_cache
+CACHE_DIRNAME=script_mediaprem_cache
+
+# GMT zone used in remote website (NOT in receiver)
+# positive if east GMT (like Italy) , i.e. GMT_ZONE=1
+# negative if west GMT (like USA) , i.e. GMT_ZONE=-6
+# 'equal' if receiver time is equal to remote website (same timezone)
+# default GMT_ZONE=equal
+GMT_ZONE=equal
+
+# number of days in the future for downloading EPG
+# MAX_DAY_EPG=1 means "download only today"
+# MAX_DAY_EPG=2 means "download today and tomorrow"
+# ....
+# default MAX_DAY_EPG=7
+MAX_DAY_EPG=7
+
+# MEDIASET EPG HTML repository
+# default URL=http://www.mediasetpremium.mediaset.it/export/palinsesto.xml
+URL=http://www.mediasetpremium.mediaset.it/export/palinsesto.xml
+
+
+# ==================================================================================================
+# CHANNEL configuration section
+[channels]
+
+#
+# YOU must configure every channel ID
+#
+# id=0                       EPG will not be downloaded
+# id=1,LAMEDB_channel_name   EPG will be downloaded and cached
+# id=2,LAMEDB_channel_name   EPG will be downloaded every time
+# id=3,LAMEDB_channel_name   EPG will be downloaded and cached (like '1') but only TODAY will be forced downloading (like '2')
+#
+# Examples:
+# KE=0                  channel id 'KE' (Premium Cinema) EPG will NOT be dowloaded
+# KE=1,PremiumCinema    'KE' EPG will be dowloaded and cached and it's name in lamedb is 'PremiumCinema'
+# KE=2,Premium Cinema   'KE' EPG will be dowloaded every time and it's name in lamedb is 'Premium Cinema'
+#
+# note 1: channel name is case insensitive
+# note 2: you can add many channel name using '|' character as separator (epg will be copied for all these channels)
+#          i.e.  KE=1,PremiumCinema|Premium Cinema|CinemaPremium
+#
+
+# Premium Cinema , id=KE
+KE=1,Premium Cinema
+
+# Premium Cinema Emotion , id=KO
+KO=1,Premium Emotion
+
+# Premium Cinema Energy , id=KG
+KG=1,Premium Energy
+
+# Premium Extra , id=K8
+K8=1,Premium Extra 1
+
+# Premium Extra 2 , id=K9
+K9=1,Premium Extra 2
+
+# Studio Universal , id=KR
+KR=1,Studio Universal - Premium
+
+# Joi , id=KJ
+KJ=1,Joi - Premium
+
+# Mya , id=KD
+KD=1,Mya - Premium
+
+# Steel , id=KS
+KS=1,Steel - Premium
+
+# Disney , id=DY
+DY=0,Disney Channel - Premium
+
+# Playhouse , id=KP
+KP=0,Playhouse Disney - Premium
+
+# Cartoon Network , id=KN
+KN=0,Cartoon Network - Premium
+
+# Hiro , id=KU
+KU=0,Hiro - Premium
+
+# Premium Calcio , id=KC
+KC=0,Premium Calcio
+
+# Premium Calcio 1 , id=K1
+K1=0,Premium Calcio 1
+
+# Premium Calcio 2 , id=K2
+K2=0,Premium Calcio 2
+
+# Premium Calcio 3 , id=K3
+K3=0,Premium Calcio 3
+
+# Premium Calcio 4 , id=K4
+K4=0,Premium Calcio 4
+
+# Premium Calcio 5 , id=K5
+K5=0,Premium Calcio 5
+
+# Premium Calcio 6 , id=K6
+K6=0,Premium Calcio 6
+
+
+
Index: ipk/source/epg_crossepg_0_61/var/crossepg/scripts/mediaprem/mediaprem.py
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/scripts/mediaprem/mediaprem.py	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/scripts/mediaprem/mediaprem.py	(revision 6505)
@@ -0,0 +1,593 @@
+#!/usr/bin/python
+# mediaprem.py  by Ambrosa http://www.ambrosa.net
+# this module is used for download EPG data from Mediaset website
+# derived from E2_LOADEPG
+
+__author__ = "ambrosa http://www.ambrosa.net"
+__copyright__ = "Copyright (C) 2008-2011 Alessandro Ambrosini"
+__license__ = "CreativeCommons by-nc-sa http://creativecommons.org/licenses/by-nc-sa/3.0/"
+
+import gc
+import os
+import sys
+import time
+import codecs
+import socket
+import urllib
+import urllib2
+import ConfigParser
+#from xml.dom import minidom
+
+# import CrossEPG functions
+import crossepg
+
+# location of local python modules under "scripts/lib" dir.
+# add it to sys.path()
+crossepg_instroot = crossepg.epgdb_get_installroot()
+if crossepg_instroot == False:
+	sys.exit(1)
+libdir = os.path.join(crossepg_instroot , 'scripts/lib')
+sys.path.append(libdir)
+
+# import local modules
+import sgmllib
+import scriptlib
+
+# =================================================================
+# HTML PARSER used for parsing description
+
+
+class Description_parser(sgmllib.SGMLParser):
+	def parse(self, s):
+		self.feed(s)
+		self.close()
+
+	def __init__(self, verbose=0):
+		sgmllib.SGMLParser.__init__(self, verbose)
+		self.start_div_box = False
+		self.start_div_boxtxt = False
+		self.description = ''
+
+
+	def start_div(self, attributes):
+		for name, value in attributes:
+			if name == "class":
+				if value == "box_Text":
+					self.start_div_box = True
+				elif value == "txtBox_cms":
+					self.start_div_boxtxt = True
+
+	def end_div(self):
+		if self.start_div_boxtxt == True:
+			self.start_div_box = False
+			self.start_div_boxtxt = False
+
+
+	def handle_data(self, data):
+		if self.start_div_boxtxt == True:
+			self.description += data.decode('iso-8859-1')
+
+	def get_descr(self):
+		return (self.description.strip(' \n\r') )
+
+
+
+# =================================================================
+
+
+class main(sgmllib.SGMLParser):
+
+	# main config file
+	CONF_CONFIGFILENAME = "mediaprem.conf"
+
+	# Network socket timeout (in seconds)
+	CONF_SOCKET_TIMEOUT = 20
+
+	# log text
+	CONF_LOG_SCRIPT_NAME = "MediasetPremium (Italy)"
+	CONF_LOG_PREFIX = ""
+
+	# max chars in description
+	CONF_DLDESCMAXCHAR = 250
+
+	# retry number if HTTP error
+	HTTP_ERROR_RETRY = 3
+	# seconds to wait between retries
+	HTTP_ERROR_WAIT_RETRY = 5
+
+	# charset used in remote website epg data
+	REMOTE_EPG_CHARSET = 'utf-8'
+
+	TODAYMP = ''
+	DAYCACHEMP = []
+	FIELD_SEPARATOR = '###'
+	CHANNELLIST = {}
+
+	DESCRIPTIONS_WEBCACHE = {}
+
+
+# -------- xml processing using SGMLLIB -----------
+# best way is use xml.minidom but it's very memory hungry (about 40MB memory for 2 MB XML file)
+# sgmllib can simple parse xml data
+	SGML_PALINSESTO_INSIDE = False
+	SGML_TITOLO_INSIDE = False
+	SGML_LINKSCHEDA_INSIDE = False
+
+	SGML_GIORNOMP = None
+	SGML_CHID = None
+	SGML_FD = None
+	SGML_TOTAL_EVENTS = 0
+
+	SGML_EVENT_STARTHOUR = None
+	SGML_EVENT_TITLE = None
+	SGML_EVENT_SUMMARIE = None
+
+	def parse(self, s):
+			self.feed(s)
+			self.close()
+
+	def start_palinsesto(self, attr):
+		self.SGML_PALINSESTO_INSIDE = True
+
+	def end_palinsesto(self):
+		self.SGML_PALINSESTO_INSIDE = False
+		self.SGML_GIORNOMP = None
+		self.log("extracted %d events" % self.SGML_TOTAL_EVENTS)
+
+	def start_giorno(self,attr):
+		if self.SGML_PALINSESTO_INSIDE == True :
+			self.SGML_GIORNOMP = None
+			for name,value in attr:
+				if name == "data":
+					if str(value).strip(' \n\r') in self.DAYCACHEMP :
+						self.SGML_GIORNOMP = str(value).strip(' \n\r')
+					break
+
+	def end_giorno(self):
+		self.SGML_GIORNOMP = None
+
+	def start_canale(self,attr):
+		if self.SGML_GIORNOMP != None:
+			for name,value in attr:
+				if name == "id":
+					self.SGML_CHID = str(value).strip(' \n\r').lower()
+
+					if not self.CHANNELLIST.has_key(self.SGML_CHID) :
+							self.log("Warning: new channel id=%s found in XML data" % self.SGML_CHID )
+							break
+
+					# get cache option
+					#  0 : don't download/cache
+					#  1 : download and cache (optional 1,new_name )
+					#  2 : always download overwriting existing files (optional 2,new_name )
+					#  3 : always download overwriting existing files only for TODAY (optional 3,new_name )
+
+					cacheopt = int(self.CHANNELLIST[self.SGML_CHID].split(",")[0])
+
+					# if cacheopt == 0, do nothing
+					if cacheopt == 0:
+						break
+
+					channel_name = ''
+					if len(self.CHANNELLIST[self.SGML_CHID].split(",")) > 1 :
+						if self.CHANNELLIST[self.SGML_CHID].split(",")[1] != '' :
+							# channel renamed, new name provided by user
+							channel_name = self.CHANNELLIST[self.SGML_CHID].split(",")[1].strip(' \n\r').lower()
+
+					# if channel name is not present as option, quit with error
+					if channel_name == '':
+						self.log("ERROR ! ID=%s channel name not present" % self.SGML_CHID)
+						sys.exit(1)
+
+					channel_provider = self.CONF_DEFAULT_PROVIDER
+					if len(self.CHANNELLIST[self.SGML_CHID].split(",")) > 2 :
+						if self.CHANNELLIST[self.SGML_CHID].split(",")[2] != '' :
+							channel_provider = self.CHANNELLIST[self.SGML_CHID].split(",")[2].strip(' \n\r').lower()
+
+					# if channel name is not present as option in channel_list.conf , quit with error
+					if channel_name == '':
+						self.log("ERROR ! ID=" + self.SGML_CHID + " channel name not present. Skip !")
+						break
+
+					day = str(self.convert_daymp(self.SGML_GIORNOMP))
+					eventfilename = scriptlib.fn_escape(self.SGML_CHID + self.FIELD_SEPARATOR + channel_name + self.FIELD_SEPARATOR + day)
+					eventfilepath = os.path.join(self.CONF_CACHEDIR, eventfilename)
+					if (cacheopt == 1) and os.path.exists(eventfilepath):
+						break
+					if (cacheopt == 3) and os.path.exists(eventfilepath) and (self.SGML_GIORNOMP != self.TODAYMP):
+						break
+					if (cacheopt != 1) and (cacheopt != 2) and (cacheopt != 3):
+						self.log("Warning: unknown cache option " + str(cacheopt))
+						break
+
+					self.log("  Writing in cache \'" + eventfilename + "\'",2)
+					self.log2video(" extracting \"%s\" (%s)" % (channel_name, day))
+
+					self.SGML_FD = codecs.open(eventfilepath,"w",'utf-8')
+
+					self.SGML_FD.write(self.SGML_CHID + self.FIELD_SEPARATOR + channel_name + self.FIELD_SEPARATOR + channel_provider + self.FIELD_SEPARATOR + day + '\n')
+					self.SGML_FD.write("Local Time (human readeable)###Unix GMT Time###Event Title###Event Description\n")
+
+					break
+
+	def end_canale(self):
+		if self.SGML_FD != None:
+			self.SGML_FD.close()
+		self.SGML_FD = None
+		self.SGML_CHID = None
+
+	def start_prg(self,attr):
+		if self.SGML_FD != None :
+			self.SGML_EVENT_STARTHOUR = None
+			for name,value in attr:
+				if name == "orainizio":
+					self.SGML_EVENT_STARTHOUR = str(value).strip(' \n\r')
+					break
+
+	def end_prg(self):
+		if self.SGML_FD != None :
+
+			if (self.SGML_EVENT_STARTHOUR >='00:00') and (self.SGML_EVENT_STARTHOUR <= '05:59') :
+				nextdayevent = 86400
+			else:
+				nextdayevent = 0
+
+			event_starttime = self.SGML_GIORNOMP + '_' + self.SGML_EVENT_STARTHOUR
+			event_startime_unix_gmt = str(int(time.mktime(time.strptime(event_starttime,"%Y/%m/%d_%H:%M"))) - self.DELTA_UTC + nextdayevent)
+
+			event_title = unicode(self.SGML_EVENT_TITLE)
+			event_title = event_title.replace('\r','')
+			event_title = event_title.replace('\n','')
+			event_title = event_title.strip(u' ')
+
+			event_description = ''
+			if self.CONF_DL_DESC == 1 :
+				event_description = unicode(self.get_description(self.SGML_EVENT_SUMMARIE_LINK.strip(' \n\r'), self.CONF_DLDESCMAXCHAR) )
+				event_description = event_description.replace('\r','')
+				event_description = event_description.replace('\n',u' ')
+				event_description = event_description.strip(u' ')
+
+			self.SGML_FD.write(event_starttime + self.FIELD_SEPARATOR + event_startime_unix_gmt + self.FIELD_SEPARATOR + event_title + self.FIELD_SEPARATOR + event_description + '\n')
+			self.SGML_TOTAL_EVENTS += 1
+
+	def start_titolo(self,attr):
+		if self.SGML_FD != None:
+			self.SGML_TITOLO_INSIDE = True
+
+	def end_titolo(self):
+		if self.SGML_FD != None:
+			self.SGML_TITOLO_INSIDE = False
+
+	def start_linkscheda(self,attr):
+		if self.SGML_FD != None:
+			self.SGML_LINKSCHEDA_INSIDE = True
+
+	def end_linkscheda(self):
+		if self.SGML_FD != None:
+			self.SGML_LINKSCHEDA_INSIDE = False
+
+
+	def handle_data(self, data):
+		if self.SGML_TITOLO_INSIDE == True:
+			self.SGML_EVENT_TITLE = data.encode('utf-8')
+			self.SGML_EVENT_TITLE = self.SGML_EVENT_TITLE.strip(' \n\r')
+
+		if self.SGML_LINKSCHEDA_INSIDE == True:
+			self.SGML_EVENT_SUMMARIE_LINK = data.encode('utf-8')
+			self.SGML_EVENT_SUMMARIE_LINK = self.SGML_EVENT_SUMMARIE_LINK.strip(' \n\r')
+
+
+# -----------------------------------------------
+
+	def log(self,s,video=0):
+		self.logging.log(self.CONF_LOG_PREFIX + str(s))
+		if video == 1:
+			self.log2video(str(s))
+
+	def log2video(self,s):
+		self.logging.log2video_status(str(s))
+
+	def convert_daymp(self,dmp):
+		daystandard = time.strftime("%Y%m%d",time.strptime(dmp,"%Y/%m/%d"))
+		return daystandard
+
+
+	def get_description(self,url,maxchar=128):
+
+		if url[:7] != 'http://':
+			return('')
+
+		if (url[-5:] != '.html') and (url[-4:] != '.htm') :
+			return('')
+
+		url_hash = hash(url)
+		if self.DESCRIPTIONS_WEBCACHE.has_key(url_hash):
+			self.log("   cached description " + url)
+			return(self.DESCRIPTIONS_WEBCACHE[url_hash])
+
+		self.log("   downloading description " + url )
+		url_enc = str(urllib.quote(url,safe=":/"))
+		try:
+			sock = urllib2.urlopen(url_enc)
+			data = sock.read()
+		except IOError, e:
+			serr = "unknown"
+			if hasattr(e, 'reason'):
+				serr = str(e.reason)
+			elif hasattr(e, 'code'):
+				serr = str(e.code)
+				if hasattr(e, 'msg'):
+					serr += " , " + str(e.msg)
+
+			self.log("      error, reason: " + serr + ". Skip it.")
+			return('')
+
+		else:
+			sock.close()
+			dsparser = Description_parser()
+			dsparser.parse(data)
+			self.DESCRIPTIONS_WEBCACHE[url_hash] = dsparser.get_descr()[:maxchar]
+			return(self.DESCRIPTIONS_WEBCACHE[url_hash])
+
+		return('')
+
+
+
+	def __init__(self, confdir, dbroot):
+
+		# initialize SGMLLIB
+		sgmllib.SGMLParser.__init__(self, 0)
+
+		# initialize logging
+		self.logging = scriptlib.logging_class()
+		# write to video OSD the script name
+		self.logging.log2video_scriptname(self.CONF_LOG_SCRIPT_NAME)
+
+		CONF_FILE = os.path.join(confdir,self.CONF_CONFIGFILENAME)
+		if not os.path.exists(CONF_FILE) :
+			self.log("ERROR: %s not present" % CONF_FILE,1)
+			sys.exit(1)
+
+		config = ConfigParser.ConfigParser()
+		#config.optionxform = str  # needed to return case sensitive index
+		config.read(CONF_FILE)
+
+		# reading [global] section options
+		self.CONF_DEFAULT_PROVIDER = config.get("global","DEFAULT_PROVIDER")
+		# save cache under dbroot
+		self.CONF_CACHEDIR = os.path.join(dbroot,config.get("global","CACHE_DIRNAME"))
+
+		self.CONF_DL_DESC = config.getint("global","DL_DESC")
+		self.CONF_MAX_DAY_EPG = config.getint("global","MAX_DAY_EPG")
+		self.CONF_URL = config.get("global","URL")
+
+		self.CONF_GMT_ZONE = config.get("global","GMT_ZONE")
+		if self.CONF_GMT_ZONE.strip(' ').lower() == 'equal':
+			#self.DELTA_UTC = -scriptlib.delta_utc() # return negative if timezone is east of GMT (like Italy), invert sign
+			self.DELTA_UTC = 0
+		else:
+			self.DELTA_UTC = float(self.CONF_GMT_ZONE)*3600.0
+			if self.DELTA_UTC >= 0:
+				self.DELTA_UTC = self.DELTA_UTC + scriptlib.delta_dst()
+			else:
+				self.DELTA_UTC = self.DELTA_UTC - scriptlib.delta_dst()
+
+		self.DELTA_UTC = int(self.DELTA_UTC)
+		#self.log("Website timezone - UTC = %d seconds" % self.DELTA_UTC)
+
+		if not os.path.exists(self.CONF_CACHEDIR):
+			self.log("Creating \'%s\' directory for caching" % self.CONF_CACHEDIR)
+			os.mkdir(self.CONF_CACHEDIR)
+
+		# reading [channels] section
+		temp = config.items("channels");
+
+		# create a dictionary (Python array) with index = channel ID
+		for i in temp:
+			self.CHANNELLIST[i[0].strip(' \n\r').lower()] = unicode(i[1].strip(' \n\r').lower(),'utf-8')
+
+		if len(self.CHANNELLIST) == 0 :
+			self.log("ERROR: [channels] section empty ?",1)
+			sys.exit(1)
+
+		# set network socket timeout
+		socket.setdefaulttimeout(self.CONF_SOCKET_TIMEOUT)
+
+		self.TODAYMP = time.strftime("%Y/%m/%d")
+		# create a list filled with dates (format AAAA/MM/DD) from today to today+ MAX_DAY_EPG
+		self.DAYCACHEMP=[]
+		for day in range(0,self.CONF_MAX_DAY_EPG):
+			self.DAYCACHEMP.append(time.strftime("%Y/%m/%d",time.localtime(time.time()+86400*day)))
+
+
+
+# ----------------------------------------------------------------------
+
+
+	def download_and_cache(self):
+		self.log("--- START DOWNLOAD AND CACHE DATA ---")
+		self.log2video("STARTING DOWNLOAD")
+
+		self.log("Removing old cached files")
+		scriptlib.cleanup_oldcachedfiles(self.CONF_CACHEDIR, self.FIELD_SEPARATOR)
+
+
+		self.log("Start download XML data from \'" + self.CONF_URL+"\'")
+		self.log2video("downloading XML data ...")
+
+		i = self.HTTP_ERROR_RETRY
+		while i > 0:
+			try:
+				sock = urllib2.urlopen(self.CONF_URL)
+				data = sock.read()
+			except IOError, e:
+				serr = "unknown"
+				if hasattr(e, 'reason'):
+					serr = str(e.reason)
+				elif hasattr(e, 'code'):
+					serr = str(e.code)
+				if hasattr(e, 'msg'):
+					serr += " , " + str(e.msg)
+
+				self.log("\'" + self.CONF_URL + "\' connection error. Reason: "+serr+". Waiting "+str(self.HTTP_ERROR_WAIT_RETRY)+" sec. and retry ["+str(i)+"] ...")
+				time.sleep(self.HTTP_ERROR_WAIT_RETRY) # add sleep
+				i -= 1
+
+			else:
+				i = -99
+				sock.close()
+
+		if (i != -99):
+			self.log("Cannot retrieve data from \'" + self.CONF_URL + "\'. Abort script")
+			self.log2video("Error: cannot download XML data, abort")
+			time.sleep(5)
+			sys.exit(1)
+
+		self.log("end download XML data, now processing")
+		self.log2video("processing XML data, wait ...")
+
+		# start SGMLLIB parsing
+		self.parse(data)
+
+		self.log("end process XML data",1)
+
+# ----------------------------------------------------------------------
+
+
+	def process_cache(self):
+		self.log("--- START PROCESSING CACHE ---")
+		self.log2video("START PROCESSING CACHE")
+		if not os.path.exists(self.CONF_CACHEDIR):
+			self.log("ERROR: %s not present" % self.CONF_CACHEDIR,1)
+			sys.exit(1)
+
+		self.log("Loading lamedb")
+		lamedb = scriptlib.lamedb_class()
+
+		self.log("Initialize CrossEPG database")
+		crossdb = scriptlib.crossepg_db_class()
+		crossdb.open_db()
+
+		events = []
+		previous_id = ''
+		channels_name = ''
+		total_events = 0
+
+		self.log("Start data processing")
+		filelist = sorted(os.listdir(self.CONF_CACHEDIR))
+		filelist.append('***END***')
+
+		for f in filelist :
+			id = f.split(self.FIELD_SEPARATOR)[0]
+			if previous_id == '':
+				previous_id = id
+
+			if id != previous_id :
+				total_events += len(events)
+				self.log("  ...processing \'%s\' , nr. events %d" % (previous_id,len(events)))
+				self.log2video("processed %d events ..." % total_events )
+
+				for c in channels_name:
+					# a channel can have zero or more SID (different channel with same name)
+					# return the list [0e1f:00820000:0708:00c8:1:0 , 1d20:00820000:2fa8:013e:1:0 , ..... ]
+					# return [] if channel name is not in lamedb
+					sidbyname = lamedb.get_sid_byname(c.strip(' \n').lower())
+
+					# process every SID
+					for s in sidbyname:
+						# convert "0e1f:00820000:0708:00c8:1:0" to sid,tsid,onid
+						# return the list [sid,tsid,onid]
+						ch_sid = lamedb.convert_sid(s)
+						if len(ch_sid) == 0:
+							continue
+
+						# add channel into db
+						# doesn't matter if the channel already exist... epgdb do all the work
+						crossdb.add_channel(ch_sid)
+
+						i = 0
+						L = len(events) - 1
+
+						# process events
+						for e in events:
+
+							items = e.split(self.FIELD_SEPARATOR)
+							e_starttime = int(items[1])
+
+							if i < L :
+								e_length = int(events[i+1].split(self.FIELD_SEPARATOR)[1]) - e_starttime
+							else:
+								# last event, dummy length 90 min.
+								e_length = 5400
+							i += 1
+
+							# extract title and encode Python Unicode with UTF-8
+							e_title = items[2].encode('utf-8')
+
+							# extract summarie and encode Python Unicode with UTF-8
+							e_summarie = items[3].encode('utf-8')
+
+							# add_event(start_time , duration , title , summarie , ISO639_language_code , strings_encoded_with_UTF-8)
+							crossdb.add_event(e_starttime, e_length, e_title, e_summarie, 'ita', True )
+
+				if f == '***END***':
+					break
+
+				events = []
+				previous_id = id
+				channels_name = ''
+
+			if id == previous_id:
+				self.log("Reading  \'%s\'" % f)
+				# read events from cache file using UTF-8 and insert them in events list
+				fd = codecs.open(os.path.join(self.CONF_CACHEDIR, f),"r","utf-8")
+				lines = fd.readlines()
+				fd.close()
+				if channels_name == '':
+					# first line has channel data (id,name,provider,date)
+					channels_name = lines[0].split(self.FIELD_SEPARATOR)[1].split('|')
+				# the second line is only a remark
+				# add events starting from third line
+				events.extend(lines[2:])
+
+		# end process, close CrossEPG DB saving data
+		crossdb.close_db()
+		self.log("TOTAL EPG EVENTS PROCESSED: %d" % total_events)
+		self.log("--- END ---")
+		self.log2video("END , events processed: %d" % total_events)
+
+
+
+# ****************************************************************************************************************************
+
+# MAIN CODE: SCRIPT START HERE
+
+# increase this process niceness (other processes have higher priority)
+os.nice(10)
+
+# set Garbage Collector to do a "generational jump" more frequently than default 700
+# memory saving: about 50% (!!), some performance loss (obviously)
+gc.set_threshold(50,10,10)
+
+SCRIPT_DIR = 'scripts/mediaprem/'
+
+# get CrossEPG installation dir.
+crossepg_instroot = crossepg.epgdb_get_installroot()
+if crossepg_instroot == False:
+	sys.exit(1)
+scriptlocation = os.path.join(crossepg_instroot , SCRIPT_DIR)
+
+# get where CrossEPG save data (dbroot) and use it as script cache repository
+crossepg_dbroot = crossepg.epgdb_get_dbroot()
+if crossepg_dbroot == False:
+	sys.exit(1)
+
+# initialize script class
+script_class = main(scriptlocation , crossepg_dbroot)
+
+# download data and cache them
+script_class.download_and_cache()
+
+# read cached data and inject into CrossEPG database
+script_class.process_cache()
+
Index: ipk/source/epg_crossepg_0_61/var/crossepg/scripts/rai/rai.conf
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/scripts/rai/rai.conf	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/scripts/rai/rai.conf	(revision 6505)
@@ -0,0 +1,109 @@
+# rai.conf by ambrosa http://www.ambrosa.net
+# configuration file
+# 
+
+# ==================================================================================================
+# GLOBAL configuration section
+[global]
+
+# default provider used for searching channel name in lamedb
+DEFAULT_PROVIDER=rai
+
+# cache dir name
+# default CACHE_DIRNAME=script_rai_cache
+CACHE_DIRNAME=script_rai_cache
+
+# GMT zone used in remote website (NOT in receiver)
+# positive if east GMT (like Italy) , i.e. GMT_ZONE=1
+# negative if west GMT (like USA) , i.e. GMT_ZONE=-6
+# 'equal' if receiver time is equal to remote website (same timezone)
+# default GMT_ZONE=equal
+GMT_ZONE=equal
+
+# number of days in the future for downloading EPG
+# MAX_DAY_EPG=1 means "download only today"
+# MAX_DAY_EPG=2 means "download today and tomorrow"
+# ....
+# default MAX_DAY_EPG=7
+MAX_DAY_EPG=7
+
+# RAI EPG HTML repository
+# default URL=http://www.rai.it//dl/portale/GuidaProgrammiAcc.html
+URL=http://www.rai.it//dl/portale/GuidaProgrammiAcc.html
+
+
+# ==================================================================================================
+# CHANNEL configuration section
+[channels]
+
+#
+# YOU must configure every channel ID
+#
+# id=0                       EPG will not be downloaded
+# id=1,LAMEDB_channel_name   EPG will be downloaded and cached
+# id=2,LAMEDB_channel_name   EPG will be downloaded every time
+# id=3,LAMEDB_channel_name   EPG will be downloaded and cached (like '1') but only TODAY will be forced downloading (like '2')
+#
+# Examples:
+# RaiUno=0             channel id 'RaiUno' EPG will NOT be dowloaded
+# RaiUno=1,rai 1       'RaiUno' EPG will be dowloaded and cached and it's name in lamedb is 'rai 1'
+# RaiUno=2,rai1        'RaiUno' EPG will be dowloaded every time and it's name in lamedb is 'rai1'
+#
+# note 1: channel name is case insensitive
+# note 2: you can add many channel name using '|' character as separator (epg will be copied for all these channels)
+#          i.e.  RaiTre=1,rai3|rai 3|rai tre lombardia
+#
+
+
+# BE AWARE : rai channel ID are CASE SENSITIVE , don't change them
+
+
+# RAI1 , id=RaiUno
+RaiUno=0,rai1|rai 1|rai hd|rai test hd
+
+# RAI2 , id=RaiDue
+RaiDue=0,rai2|rai 2
+
+# RAI3 , id=RaiTre
+RaiTre=0,rai3|rai 3|rai 3 tgr lombardia
+
+# RAI4 , id=Rai4
+Rai4=1,rai 4
+
+# Rai5, id=Extra
+Extra=1,rai 5
+
+# Rai Sport 1 , id=RaiSport1
+RaiSport1=0,rai sport 1
+
+# Rai Sport 2 , id=RaiSport2
+RaiSport2=0,rai sport 2
+
+# Rai Scuola , id=RaiEducational
+RaiEducational=0,rai scuola
+
+# Rai Premium, id=Premium
+Premium=1,rai premium
+
+# Rai YoYo, id=Yoyo
+Yoyo=1,rai yoyo
+
+# Rai Movie, id=CinemaWorld
+CinemaWorld=1,rai movie
+
+# Rai Gulp, id=RaiGulp
+RaiGulp=1,rai gulp
+
+# Rai EDU2, id=RaiEDU2
+RaiEDU2=1,rai storia
+
+# RADIO1 , id=RadioUno
+RadioUno=0,rai radio1
+
+# RADIO2 , id=RadioDue
+RadioDue=0,rai radio2
+
+# RADIO3 , id=RadioTre
+RadioTre=0,rai radio3
+
+
Index: ipk/source/epg_crossepg_0_61/var/crossepg/scripts/rai/rai.py
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/scripts/rai/rai.py	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/scripts/rai/rai.py	(revision 6505)
@@ -0,0 +1,498 @@
+#!/usr/bin/python
+# rai.py  by Ambrosa http://www.ambrosa.net
+# this module is used for download EPG data from Rai website
+# derived from E2_LOADEPG
+
+__author__ = "ambrosa http://www.ambrosa.net"
+__copyright__ = "Copyright (C) 2008-2011 Alessandro Ambrosini"
+__license__ = "CreativeCommons by-nc-sa http://creativecommons.org/licenses/by-nc-sa/3.0/"
+
+import os
+import sys
+import time
+import codecs
+import socket
+import string
+import random
+import urllib2
+import ConfigParser
+
+# import CrossEPG functions
+import crossepg
+
+# location of local python modules under "scripts/lib" dir.
+# add it to sys.path()
+crossepg_instroot = crossepg.epgdb_get_installroot()
+if crossepg_instroot == False:
+	sys.exit(1)
+libdir = os.path.join(crossepg_instroot , 'scripts/lib')
+sys.path.append(libdir)
+
+# import local modules
+import sgmllib
+import scriptlib
+
+# =================================================================
+# HTML PARSER
+
+class Titolo_parser(sgmllib.SGMLParser):
+
+	def parse(self, s):
+		self.feed(s)
+		self.close()
+
+	def __init__(self, day_get, verbose=0):
+		sgmllib.SGMLParser.__init__(self, verbose)
+		self.daynow = day_get
+		self.daynext = time.strftime("%Y%m%d",time.localtime(time.mktime(time.strptime(day_get,"%Y%m%d"))+86400))
+		self.day = self.daynow
+		self.guidatoday = []
+		self.guidatomorrow = []
+		self.sera = False
+		self.tomorrow = False
+		self.start_orario = False
+		self.start_titolo = False
+		self.inside_a_titolo = False
+		self.inside_palinsesto = False
+
+
+	def start_div(self,attributes):
+		for name,value in attributes:
+			if name == "class":
+				if value == "intG":
+					self.inside_palinsesto = True
+
+	def start_span(self, attributes):
+		if self.inside_palinsesto == True:
+			for name, value in attributes:
+				if name == "class":
+					if value == "ora":
+						self.start_orario = True
+					if value == "info":
+						self.start_titolo = True
+
+	def start_a(self,attributes):
+		if self.inside_palinsesto == True:
+			if self.start_titolo == True:
+				self.inside_a_titolo = True
+
+	def handle_data(self, data):
+		if self.inside_palinsesto == True:
+
+			if self.start_orario == True:
+
+				# if time < 06:00 is a next day event
+				if int(time.strftime("%H",time.strptime(data,"%H:%M"))) < 6 :
+					self.day = self.daynext
+					self.tomorrow = True
+				else:
+					if self.tomorrow == True:
+						self.inside_a_titolo = False
+						self.start_titolo = False
+						self.inside_palinsesto = False
+						return
+
+				self.dataoraevento = time.strftime("%Y-%m-%d %H:%M",time.strptime(self.day+'-'+data,"%Y%m%d-%H:%M"))
+				self.start_orario = False
+
+			if self.inside_a_titolo == True:
+				if self.tomorrow == False:
+					self.guidatoday.append((self.dataoraevento,data.strip()))
+				else:
+					self.guidatomorrow.append((self.dataoraevento,data.strip()))
+
+				self.inside_a_titolo = False
+				self.start_titolo = False
+				self.inside_palinsesto = False
+
+
+	def get_guida(self):
+		return ((self.guidatoday,self.guidatomorrow))
+
+
+# =================================================================
+
+
+class main:
+
+	# main config file
+	CONF_CONFIGFILENAME = "rai.conf"
+
+	# Network socket timeout (in seconds)
+	CONF_SOCKET_TIMEOUT = 20
+
+	# log text
+	CONF_LOG_SCRIPT_NAME = "RAI (Italy)"
+	CONF_LOG_PREFIX = "RAI: "
+
+	# retry number if HTTP error
+	HTTP_ERROR_RETRY = 3
+	# seconds to wait between retries
+	HTTP_ERROR_WAIT_RETRY = 5
+
+	# random time delay (in seconds) between access to remote web pages
+	CONF_RANDOM_MIN = 0.0
+	CONF_RANDOM_MAX = 2.0
+
+	# charset used in remote website epg data
+	REMOTE_EPG_CHARSET = 'utf-8'
+
+	TODAY = ''
+	DAYCACHE = []
+	FIELD_SEPARATOR = '###'
+	CHANNELLIST = {}
+
+
+	def log(self,s,video=0):
+		self.logging.log(self.CONF_LOG_PREFIX + str(s))
+		if video == 1:
+			self.log2video(str(s))
+
+	def log2video(self,s):
+		self.logging.log2video_status(str(s))
+
+
+	def __init__(self,confdir,dbroot):
+
+		# initialize logging
+		self.logging = scriptlib.logging_class()
+		# write to video OSD the script name
+		self.logging.log2video_scriptname(self.CONF_LOG_SCRIPT_NAME)
+
+
+		CONF_FILE = os.path.join(confdir,self.CONF_CONFIGFILENAME)
+		if not os.path.exists(CONF_FILE) :
+			self.log("ERROR: %s not present" % CONF_FILE,1)
+			sys.exit(1)
+
+		config = ConfigParser.ConfigParser()
+		config.optionxform = str  # needed to return case sensitive index
+		config.read(CONF_FILE)
+
+		# reading [global] section options
+		self.CONF_DEFAULT_PROVIDER = config.get("global","DEFAULT_PROVIDER")
+		# save cache under dbroot
+		self.CONF_CACHEDIR = os.path.join(dbroot,config.get("global","CACHE_DIRNAME"))
+
+		self.CONF_MAX_DAY_EPG = config.getint("global","MAX_DAY_EPG")
+		self.CONF_URL = config.get("global","URL")
+
+		self.CONF_GMT_ZONE = config.get("global","GMT_ZONE")
+		if self.CONF_GMT_ZONE.strip(' ').lower() == 'equal':
+			#self.DELTA_UTC = -scriptlib.delta_utc() # return negative if timezone is east of GMT (like Italy), invert sign
+			self.DELTA_UTC = 0
+		else:
+			self.DELTA_UTC = float(self.CONF_GMT_ZONE)*3600.0
+			if self.DELTA_UTC >= 0:
+				self.DELTA_UTC = self.DELTA_UTC + scriptlib.delta_dst()
+			else:
+				self.DELTA_UTC = self.DELTA_UTC - scriptlib.delta_dst()
+
+		self.DELTA_UTC = int(self.DELTA_UTC)
+		#self.log("Website timezone - UTC = %d seconds" % self.DELTA_UTC)
+
+		if not os.path.exists(self.CONF_CACHEDIR):
+			self.log("Creating \'%s\' directory for caching" % self.CONF_CACHEDIR)
+			os.mkdir(self.CONF_CACHEDIR)
+
+		# reading [channels] section
+		temp=config.items("channels");
+
+		# create a dictionary (Python array) with index = channel ID
+		for i in temp:
+			self.CHANNELLIST[i[0]] = unicode(i[1],'utf-8')
+
+		if len(self.CHANNELLIST) == 0 :
+			self.log("ERROR: [channels] section empty ?",1)
+			sys.exit(1)
+
+		# set network socket timeout
+		socket.setdefaulttimeout(self.CONF_SOCKET_TIMEOUT)
+
+		# initialize random generator
+		random.seed()
+
+		# today date (format AAAAMMDD)
+		self.TODAY = time.strftime("%Y%m%d")
+
+		# create a list filled with dates (format AAAAMMDD) from today to today+MAX_DAY_EPG
+		self.DAYCACHE=[self.TODAY]
+		for day in range(1,self.CONF_MAX_DAY_EPG):
+			self.DAYCACHE.append(time.strftime("%Y%m%d",time.localtime(time.time()+86400*day)))
+
+
+# ----------------------------------------------------------------------
+
+
+	def download_and_cache(self):
+		self.log("--- START DOWNLOAD AND CACHE DATA ---")
+		self.log2video("STARTING DOWNLOAD")
+
+		self.log("Removing old cached files")
+		scriptlib.cleanup_oldcachedfiles(self.CONF_CACHEDIR, self.FIELD_SEPARATOR)
+
+		#self.log("Start downloading HTML data from \'%s\'" % self.CONF_URL)
+
+		chlist = self.CHANNELLIST
+
+		# get remote XML files
+		#   chid format: channel id , 0|1|2(,new name)
+		#   i.e. ("101" , "1,SkyCinema1")
+		for c in sorted(chlist.keys()):
+			self.guidatoday = []
+			self.guidatomorrow = []
+
+			# get cache option
+			#  0 : don't download/cache
+			#  1 : download and cache (optional 1,new_name )
+			#  2 : always download overwriting existing files (optional 2,new_name )
+			#  3 : always download overwriting existing files only for TODAY (optional 3,new_name )
+
+			cacheopt = int(string.split(chlist[c],",")[0])
+
+			# if cacheopt == 0, do nothing
+			if cacheopt == 0:
+				continue
+
+			channel_name = ''
+			if len(chlist[c].split(",")) > 1 :
+				if chlist[c].split(",")[1] != '' :
+					# channel renamed, new name provided by user
+					channel_name = chlist[c].split(",")[1].strip(' ').lower()
+
+			# if channel name is not present as option, quit with error
+			if channel_name == '':
+				self.log("ERROR ! ID=%s channel name not present" % c, 1)
+				sys.exit(1)
+
+			channel_provider = self.CONF_DEFAULT_PROVIDER
+			if len(chlist[c].split(",")) > 2 :
+				if chlist[c].split(",")[2] != '' :
+					channel_provider = chlist[c].split(",")[2].strip(' ').lower()
+
+			exit_for_loop = False
+			for day in self.DAYCACHE:
+				if exit_for_loop == True:
+					break
+
+				day_get = time.strftime("%Y_%m_%d",time.strptime(day,"%Y%m%d"))
+				xmlfile = "?%s_%s" % (c,day_get)
+
+				# download only if file doesn't exist or cacheopt == 2 (always download),
+				# using open(...,"w") files will be overwritten (saving a delete + create)
+
+				eventfilename = scriptlib.fn_escape(str(c) + self.FIELD_SEPARATOR + channel_name + self.FIELD_SEPARATOR + day)
+				eventfilepath = os.path.join(self.CONF_CACHEDIR, eventfilename)
+				if (cacheopt == 1) and os.path.exists(eventfilepath):
+					continue
+				if (cacheopt == 3) and os.path.exists(eventfilepath) and (day != self.TODAY):
+					continue
+				if (cacheopt != 1) and (cacheopt != 2) and (cacheopt != 3):
+					self.log("Warning: unknown cache option " + str(cacheopt))
+					exit_for_loop = True
+					continue
+
+				self.log("Download HTML data from \'%s\'" % (self.CONF_URL + xmlfile))
+				self.log2video("Download " + c)
+
+				i = self.HTTP_ERROR_RETRY
+				while i > 0  :
+					#  wait randomly to avoid overloading website
+					time.sleep(random.uniform(self.CONF_RANDOM_MIN, self.CONF_RANDOM_MAX))
+
+					try:
+						sock=urllib2.urlopen(self.CONF_URL + xmlfile)
+						data=sock.read()
+
+					except IOError, e:
+						serr="unknown"
+						if hasattr(e, 'reason'):
+							serr=str(e.reason)
+						elif hasattr(e, 'code'):
+							serr=str(e.code)
+							if hasattr(e, 'msg'):
+								serr+=" , "+str(e.msg)
+
+						self.log("\'%s\' connection error. Reason: %s. Waiting %d sec. and retry [%d] ..." % (self.CONF_URL + xmlfile, serr, self.HTTP_ERROR_WAIT_RETRY, i))
+						time.sleep(self.HTTP_ERROR_WAIT_RETRY) # add sleep
+						i -= 1
+
+					else:
+						i = 0 # force quit WHILE loop
+						sock.close()
+
+						dtparser = Titolo_parser(day)
+						dtparser.parse(data)
+						self.guida = self.guidatomorrow
+						(self.guidatoday, self.guidatomorrow) = dtparser.get_guida()
+
+						# if no data, quit for loop and stop downloading
+						if len(self.guidatoday) == 0:
+							exit_for_loop = True
+							break
+
+						self.guida = self.guida + self.guidatoday
+
+						self.log("  writing in cache \'%s\'" % eventfilename)
+						# write data in cache file using UTF-8 encoding
+						fd = codecs.open(eventfilepath, "w", 'utf-8')
+						fd.write(str(c) + self.FIELD_SEPARATOR + channel_name + self.FIELD_SEPARATOR + channel_provider + self.FIELD_SEPARATOR + day + '\n')
+						fd.write("Local Time (human readeable)###Unix GMT Time###Event Title###Event Description\n")
+
+						# extract all events and put in eventfile
+						for event in self.guida:
+							(dataora,titolo) = event
+							event_starttime = dataora
+							# time.mktime return Unix time inside GMT timezone
+							event_startime_unix_gmt = str(int(time.mktime(time.strptime(event_starttime,"%Y-%m-%d %H:%M"))) - self.DELTA_UTC )
+							#event_startime_unix_gmt = str(int(time.mktime(time.strptime(event_starttime,"%Y-%m-%d %H:%M")))  )
+							#self.log(event_starttime + " , " + str(self.DELTA_UTC) + " , " + str(int(time.mktime(time.strptime(event_starttime,"%Y-%m-%d %H:%M")))) + " , " + event_startime_unix_gmt )
+
+							# convert remote data (RAI website use UTF-8) in Python Unicode (UCS2)
+							event_title = unicode(titolo,self.REMOTE_EPG_CHARSET)
+
+							event_title = event_title.replace('\r','')
+							event_title = event_title.replace('\n',u' ')
+							event_title = event_title.strip(u' ')
+
+							event_description = u''
+
+							fd.write(event_starttime + self.FIELD_SEPARATOR + event_startime_unix_gmt + self.FIELD_SEPARATOR + event_title + self.FIELD_SEPARATOR + event_description + '\n')
+
+						fd.close()
+
+
+# ----------------------------------------------------------------------
+
+
+	def process_cache(self):
+		self.log("--- START PROCESSING CACHE ---")
+		self.log2video("START PROCESSING CACHE")
+		if not os.path.exists(self.CONF_CACHEDIR):
+			self.log("ERROR: %s not present" % self.CONF_CACHEDIR,1)
+			sys.exit(1)
+
+		self.log("Loading lamedb")
+		lamedb = scriptlib.lamedb_class()
+
+		self.log("Initialize CrossEPG database")
+		crossdb = scriptlib.crossepg_db_class()
+		crossdb.open_db()
+
+		events = []
+		previous_id = ''
+		channels_name = ''
+		total_events = 0
+
+		self.log("Start data processing")
+		filelist = sorted(os.listdir(self.CONF_CACHEDIR))
+		filelist.append('***END***')
+
+		for f in filelist :
+			id = f.split(self.FIELD_SEPARATOR)[0]
+			if previous_id == '':
+				previous_id = id
+
+			if id != previous_id :
+				total_events += len(events)
+				self.log("  ...processing \'%s\' , nr. events %d" % (previous_id,len(events)))
+				self.log2video("processed %d events ..." % total_events )
+
+				for c in channels_name:
+					# a channel can have zero or more SID (different channel with same name)
+					# return the list [0e1f:00820000:0708:00c8:1:0 , 1d20:00820000:2fa8:013e:1:0 , ..... ]
+					# return [] if channel name is not in lamedb
+					sidbyname = lamedb.get_sid_byname(c.strip(' \n').lower())
+
+					# process every SID
+					for s in sidbyname:
+						# convert "0e1f:00820000:0708:00c8:1:0" to sid,tsid,onid
+						# return the list [sid,tsid,onid]
+						ch_sid = lamedb.convert_sid(s)
+						if len(ch_sid) == 0:
+							continue
+
+						# add channel into db
+						# doesn't matter if the channel already exist... epgdb do all the work
+						crossdb.add_channel(ch_sid)
+
+						i = 0
+						L = len(events) - 1
+
+						# process events
+						for e in events:
+
+							e_starttime = int(e.split(self.FIELD_SEPARATOR)[1])
+
+							if i < L :
+								e_length = int(events[i+1].split(self.FIELD_SEPARATOR)[1]) - e_starttime
+							else:
+								# last event, dummy length 90 min.
+								e_length = 5400
+							i += 1
+
+							# extract title and encode Python Unicode with UTF-8
+							e_title = e.split(self.FIELD_SEPARATOR)[2].encode('utf-8')
+
+							# RAI website HAVE NOT long description. (bleah !).
+							e_summarie = u' '
+							# encode Python Unicode in UTF-8
+							e_summarie = e_summarie.encode('utf-8')
+
+							# add_event(start_time , duration , title , summarie , ISO639_language_code , strings_encoded_with_UTF-8)
+							crossdb.add_event(e_starttime, e_length, e_title, e_summarie, 'ita', True )
+
+				if f == '***END***':
+					break
+
+				events = []
+				previous_id = id
+				channels_name = ''
+
+			if id == previous_id:
+				self.log("Reading  \'%s\'" % f)
+				# read events from cache file using UTF-8 and insert them in events list
+				fd = codecs.open(os.path.join(self.CONF_CACHEDIR, f),"r","utf-8")
+				lines = fd.readlines()
+				fd.close()
+				if channels_name == '':
+					# first line has channel data (id,name,provider,date)
+					channels_name = lines[0].split(self.FIELD_SEPARATOR)[1].split('|')
+				# the second line is only a remark
+				# add events starting from third line
+				events.extend(lines[2:])
+
+		# end process, close CrossEPG DB saving data
+		crossdb.close_db()
+		self.log("TOTAL EPG EVENTS PROCESSED: %d" % total_events)
+		self.log("--- END ---")
+		self.log2video("END , events processed: %d" % total_events)
+
+
+
+# ****************************************************************************************************************************
+
+# MAIN CODE: SCRIPT START HERE
+
+SCRIPT_DIR = 'scripts/rai/'
+
+# get CrossEPG installation dir.
+crossepg_instroot = crossepg.epgdb_get_installroot()
+if crossepg_instroot == False:
+	sys.exit(1)
+scriptlocation = os.path.join(crossepg_instroot , SCRIPT_DIR)
+
+# get where CrossEPG save data (dbroot) and use it as script cache repository
+crossepg_dbroot = crossepg.epgdb_get_dbroot()
+if crossepg_dbroot == False:
+	sys.exit(1)
+
+# initialize script class
+script_class = main(scriptlocation , crossepg_dbroot)
+
+# download data and cache them
+script_class.download_and_cache()
+
+# read cached data and inject into CrossEPG database
+script_class.process_cache()
+
Index: ipk/source/epg_crossepg_0_61/var/crossepg/scripts/test.py
===================================================================
--- ipk/source/epg_crossepg_0_61/var/crossepg/scripts/test.py	(revision 6505)
+++ ipk/source/epg_crossepg_0_61/var/crossepg/scripts/test.py	(revision 6505)
@@ -0,0 +1,75 @@
+#!/usr/bin/python
+# above is Python interpreter location
+
+# ambrosa 08-Jan-2011 http://www.ambrosa.net
+# this test.py program simply do nothing
+
+
+import os
+import sys
+
+# import CrossEPG module
+import crossepg
+
+# python local modules under "scripts/lib" directory
+# and add it to sys.path()
+crossepg_instroot = crossepg.epgdb_get_installroot()
+if crossepg_instroot == False:
+	print "ERROR: cannot find CrossEPG installation directory"
+	sys.exit(1)
+libdir = os.path.join(crossepg_instroot , 'scripts/lib')
+sys.path.append(libdir)
+
+# import local modules under 'scripts/lib'
+import scriptlib
+
+# -------------------------------------------------
+# this is the main function
+def main():
+
+	# log_add() print to stdout a text message
+	crossepg.log_add("---- START EXAMPLE TEST SCRIPT ----")
+
+	# get installation dir
+	instdir = crossepg.epgdb_get_installroot()
+	if instdir == False:
+		crossepg.log_add("ERROR: cannot find CrossEPG installation directory")
+		sys.exit(1)
+
+	crossepg.log_add("Installation dir : %s" % instdir)
+
+
+	# get dbroot path
+	dbroot = crossepg.epgdb_get_dbroot()
+	if dbroot == False:
+		crossepg.log_add("ERROR: cannot find CrossEPG database directory")
+		sys.exit(1)
+
+	crossepg.log_add("Database dir : %s" % dbroot)
+
+
+	# open CrossEPG internal database
+	if crossepg.epgdb_open(dbroot):
+		crossepg.log_add("EPGDB opened successfully (root = %s)" % dbroot);
+	else:
+		crossepg.log_add("Error opening EPGDB");
+		crossepg.epgdb_close();
+		sys.exit(1)
+
+	crossepg.log_add("Closing EPGDB");
+	crossepg.epgdb_close();
+
+
+	delta_timezone = scriptlib.delta_utc()
+	crossepg.log_add("GMT vs. LocalTime difference (in seconds): %d" % delta_timezone)
+	delta_daylight = scriptlib.delta_dst()
+	crossepg.log_add("DayLight Saving (DST) difference now: %d" % delta_daylight)
+	
+	
+
+	crossepg.log_add("---- END EXAMPLE TEST SCRIPT ----")
+
+# -------------------------------------------------
+# run main() function
+main()
+
