Jump to content

Archived

This topic is now archived and is closed to further replies.

coders-irc_Bot

TV v1.0.8.6

Recommended Posts

  • Administrators
ggdrop TV Skript, deutsche Fernsehsender
#
# (c) 2005-2011 thommey (Thomas Sader), CyBex, bUrN
#
# LICENSE/LIZENZ:
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 2 of the License, or
#    (at your option) any later version.
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#
##################################
### !!! MOMENTAN IN ARBEIT !!! ###
##################################
#
# Wer noch Ideen hat, oder selbst was ändert oder Fragen hat,
# meldet sich am besten hier: http://tclhelp.net/unb/144
# Dort wird auch bekannt gemacht, wenns eine neue Version
# gibt oder größere Veränderung.

# WICHTIGE AENDERUNG DER 1.0.8
# Achtung derzeit ist kein !tvsearch möglich. Diese Funktion
# wurde entfernt, aber wir haben schon Ideen.
# Es wird jetzt auch das TCL-Packet "tdom" benötigt.
# Zu finden unter https://github.com/tdom/
# Debian-Admins: apt-get install tdom

# Hilfe:
# !tv help  zeigt eine Hilfe im Chat
# !tv <sender>  zeigt die nächsten Sendungen
### !tvsearch <suchwort>  sucht halt überall im Namen nach diesem Suchwort ### Derzeit ausser Betrieb ###
# !tvadd <sender> <sendung>  fügt eine Sendung zur Beobachtungliste hinzu, die dann im Channel gemeldet wird.
# !tvdel <sender> <sendung>  entfernt wieder Sendungen.
# !tvlist  zeigt alle Sendung an, nach denen Ausschau gehalten wird.
# !addhaupt <sender>  fügt einen Sender zu den Hauptsender hinzu
# !delhaupt <sender>  entfernt einen Sender von den Hauptsender
# !tvhaupt   listet alle Hauptsender auf.
# !tv on/off  schaltet das script im channel an/aus.
# !tv list  senderliste
# !tv reload  startet das Cachen der Daten neu, falls die Daten mal nicht aktuell sein sollten. 
# !tv get  zeigt die aktuellen Rechte/Flood/Hauptsender/Design Einstellung.
# !tv set <type> <wert>  aendert die aktuelle einstellung, folgende typen sind erlaubt: allow, chanmodes, userflags, flood, haupt(sender) und design.

# Beispiele:
# !tv rtl (listet die nächsten 3 Sendung von RTL)
# !tv haupt (listet die aktuellen Sendungen von den Hauptsendern)
# !tv 2015 (listet die Hauptsender um 20:15 auf)
# !tv 23:45 (listet die Hauptsender um 23:45 auf)
### !tvsearch Simpsons (sucht nach den Simpsons) ### Derzeit ausser Betrieb ###
# !tvadd pro7 Simpsons (fügt die Simpsons zur Erinnerungsliste hinzu)
# !tvadd pro7 Family Guy (wie bei den Simpsons)
# !tvdel pro7 Simps (Entfernt das erste, was auf Simps passt, vermutlich die Simpsons)
# !tvhaupt (listet alle Hauptsender auf)
# !addhaupt ard (fügt Ard zu den Hauptsender hinzu)
# !delhaupt pro7 (löscht Pro7 von den Hauptsendern)
# !tv set allow 5 (für Channelmodes und Userflags prüfung)
# !tv set chanmodes op halfop (erlaubt nur für OPs die benutzung des TV-Scripts, sofern der Allow-Mode auf eine ChanMode prüfung steht)
# !tv set userflags +nmol|+nmol (erlaubt nur für OPs oder größer die ..., sofern der Allow-Mode auf eine UserFlag prüfung steht)
# !tv set flood 5:600 (erlaubt 5x in 10 minuten und antwortet danach als Notice und nicht mehr öffentlich)
# !tv set design horizontal (verbraucht weniger zeilen, weniger spam)
# !tv set haupt ard zdf rbb (ersetzt alle Hauptsender aufeinmal, statt mit !addhaupt einzellne hinzuzufügen)

# ideen für weiter Updates:
# (cybex) Nich nur Channel, sondern auch NICK/Persönliche Erinnerung.
# (cybex) um 20:10-20:15/andere zeit die hauptsender announcen
# (cybex) kategorien announcen
# (cybex) alles auf einen trigger !tv umstellen
# (cybex) den reminder eine von-bis zeit verpasen
# (thommey/burn) gleich eine ganze woche cachen (und tvsearch dann im cache suchen lassen)
# (thommey) cache-zeitpunkt beliebig möglich machen durch erhalten der alten daten

# Veränderungen:
#- v1.0.8.6 (CyBex)
# Bug für 23:55/00:00 angepasst
#- v1.0.8.5 (CyBex)
# Fehlerbehebung bei der Cache speicherung
# Konfiguriere 'tv.cache' Datei, liegt jetzt in /tmp damit mehrere bots einfacher drauf zugreifen können
#- v1.0.8.4 (bUrN)
# Sendungsbeschreibung (wie z.B. [Daily Soap]) wird wieder mit angezeigt
#- v1.0.8.3 (CyBex)
# HD beim Sendernamen entfernt
#- v1.0.8.2 (bUrN / CyBex)
# Anpassungen an Designänderungen (bUrN)
# !tv reload Befehl hinzugefügt (CyBex)
#- v1.0.8.1 (bUrN)
# Anpassungen an die Änderungen im Quelltext
#- v1.0.8 (bUrN)
# Anpassung an das neue Design und gleich alle Spalten auf einmal eingelesen.
#- v1.0.7.6 (CyBex)
# !tv list - senderliste
#- v1.0.7.5 (CyBex)
# BUGFIX: Sender Anzahl bei Kategorien angepasst, Kleinigkeiten beim Sender-Update
#- v1.0.7.4 (CyBex)
# Flaches Design eingefügt
#- v1.0.7.3 (CyBex)
# KanalD entfernt
#- v1.0.7.2 (CyBex)
# Dirty Hack, damit die Globalen Kategorien erstmal im groben gehen :-)
#- v1.0.7.1 (CyBex)
# Sender werden nun vor dem Cachen sortiert, so das Hauptsender und Sender auf der Erinnerungsliste
# bevorzugt werden und als erstes geholt werden
#- v1.0.7 (CyBex)
# Abschaltbare dynamische Senderliste (Neue Sender werden jetzt automatisch hinzugefügt)
# neue option für '!tv <sender> jetztgleich' zeigt an, was momentan und danach läuft.
# es geht auch als abkürzung "jg" bzw auch "jetztundgleich", die maske ist jetzt*gleich
#- v1.0.6.5 (thommey)
# html entity &rsquot; wird nun ersetzt
#- v1.0.6.4 (CyBex)
# Mini Bugfix von Nemesis eingereicht (!tv off ging nich)
#- v1.0.6.3 (CyBex)
# Hilfe und Multiple anfragen erweitert
#- v1.0.6.2 (thommey)
# TVSearch Bug entfernt
#- v1.0.6.1 (CyBex)
# Bug entfernt
#- v1.0.6 (CyBex)
# Einstellbares Triggerzeichen.. Default ! für !tv
# Optik :)
#- v1.0.6 (thommey)
# Folgen-Informationen aus der eckigen Klammer gelöst
# &bull; hinzugefügt (als / weil man das richtige nicht im irc darstellen kann)
# Die cache-Prozedur dem neuen Design angepasst
# Cache-Zeitpunkt zweckmäßig auf 5:00-5:59 verschoben (tvmovie trennt die tage dort)
# Einstellbares Triggerzeichen.. Default ! für !tv (CyBex)
#- v1.0.5.4 (CyBex)
# Der Cache wird nun gespeichert, das man beim restart nich immer erstmal alles neu laden muss
# nur "tv-op"s koennen sendungen/sender hinzufügen, string map für zeichen convertierung eingebaut
# Fehler entfernt, ab und zu blieb "cachetvdata" stehen. (Work-A-Round in der proc "chktimetv" für Leute die nur Veränderung aufnehmen wollen)
# Und es wurde noch eine Überprüfung eingebaut, ob die Cachedaten schon geladen werden, wenn das Script geladen wird. (ca. Zeile 240)
# "!tv get" verbessert
# ausversehen mit "putcmdlog"s veröffentlicht, die die Partyline ganz schön zuspamen :)
# Da ein User natürlich die Trigger missbrauchen, erstmal Rechte und Flood Protection eingeführt
#- v1.0.4.2 (CyBex)
# Dynamische Hauptsender und man kann nun einstellen ob !tv die syntax anzeigt oder die hauptsender
# !tv 2015
# tvlist sortiert
#- v1.0.3 (CyBex)
# tvsearch etwas gefixed :)
#- v1.0.2 (CyBex)
# Erinnerungsfunktion
#- v1.0.1 (CyBex)
# channel udef tvmovie zum einfachen ein/ausschalten des script ins chans
# Channel Mode +c Erkennung für benutzung von Bold/Farben
# kategorie sport, für alle Sportsender (DSF, EUROSPORT)
# channel nick(elodeon) 19
#- v1.0 (thommey) (text von CyBex) :)
# Die komplette Basis, den !tv und !tvsearch Befehl. Das ganz besonder an diesem
# Script, das es auch zur Hauptzeit um 20:15 geht, die Sender um 3 Uhr morgens vor cachen.
# Durch das Cachen is natürlich auch die Suche sehr schön möglich und hat mir auch die
# Erinnerungsfunktion ermöglicht, weil jedes mal zu dieser Seite gehen, ganz besonders um 20:15
# is tötlich und man is schneller gebant als man "GNADE" sagen kann :)

# Ich (Wir?) wünschen jedenfalls viel Spass mit diesem Script und nich vergessen,
# erstmal mit ".chanset #channel +tvmovie" anschalten. :)

# Config:
# Und diese werte werden mehr oder weniger auch nur als default Einstellung für die Channels benutzt
# Danach wird alles dynamisch im Chanfile gespeichert bzw diese werte wer bei neu hinzugefügten Channels benutzt.
# Für spezielle Channel configuration benutzt den .chanset Befehl, zB:
# .chanset #chan tv-allow 4
# .chanset #chan tv-chanmodes voice op
# .chanset #chan tv-userflags +vo-dq
# .chanset * tvflood 3:300
# Wenn ihr nochmal alle Default(Global) einstellungen laden wollt, könnt ihr das wie folgt machen:
# .chanset * tv-allow 0
# .chanset #chan tv-chanmodes
# .chanset * tv-userflags
# .chanset #chan2 tv-flood
# Alternativ kann man es mit !tv set <type> <wert> im Channel einstellen

# global-tv-allow (digit)
# 1 = Alle dürfen und es wird auch kein Chanmode oder Userflag geprüft
# 2 = Prüft die Chanmodes (isop, isvoice usw)
# 3 = Prüft die Userflags im Bot (zB +m für master, -dq für alle die nicht voice oder op haben dürfen, +m-dq ein mix aus beidem)
# 4 = Prüft die Chanmodes oder die Userflags, man braucht also eins von beidem
# 5 = Prüft die Chanmodes und die Userflags, man braucht also beides
set global-tv-allow 1

# global-tv-chan (string)
# Prüft, wenn "allow" auf 1,3 oder 4 steht.
# default: voice halfop op
# Darf nie leer ("") sein, regelt das über den allow einsteller! (sonst erkennt der Bot nich, wann er default werte laden soll)
set global-tv-chanmodes "voice halfop op"

# global-tv-flags (string)
# zB +m für master, -dq für alle die nicht voice oder op haben dürfen, +m-dq ein mix aus beidem
# * = muss beim Bot geadded sein, muss aber nich unbedingt flags haben.
# Darf nie leer ("") sein, regelt das über den allow einsteller!
#set global-tv-userflags "+nmolavgf-kdrq|+nmolavgf-kdrq"
set global-tv-userflags "*"

# global-tv-flood (digit:digit)
# Anzahl:Zeit in sekunden, aus is, wenn eins von beidem auf 0 steht.
# 3:1800 bedeutet, der Bot antwortet 3x öffentlich in 10 Minuten und schaltet dann automatisch die antwort direkt an Nick um
# set global-tv-flood 0:0 ; # aus :)
set global-tv-flood 3:1800

# global-tv-design (string) (New in 1.0.7.4)
# !tv antworten unter- oder nebeneinander
# mögliche antworten: vertikal horizontal
set global-tv-design vertikal

# global-tv-haupt (string)
# die default hauptsender
set global-tv-haupt "pro7 sat1 rtl rtl2 vox"

### global-tv-kategorien (strings in liste)
### die defautl sender kategorien
set global-tv-kategorie {
	haupt "pro7 sat1 rtl rtl2 vox"
	sport "sport1 eurosport"
	ards "ard einextra einsplus"
	zdfs "zdf zdfinfo zdfdoku"
	dritte "wdr ndr rbb mdr hr swr br"
	alt "ard zdf arte phoenix 3sat bralpha wdr"
	gez "ard zdf"
	musik "mtv mtv2 mtvmusic viva viva2 vh1"
	dvbt ""
	dvbt-berlin "ard zdf rbb sat1 pro7 kabel rtl rtl2 srtl vox sport1 eurosport arte 3sat phoenix euronews ntv n24 kika einsextra zdfdoku zdfinfo mdr ndr wdr swr tvberlin"
	berlin "tvberlin fab spreekanal"
	news "phoenix ntv n24 euronews"
	kinder "kika nick"
	premiere "premiere1 premiere3 premiere4 discoverychannel nationalgeographic"
	rrtl2 "rrtlii"
	rtlii "rtl2"
	dsf "sport1"
	kabel "kabel1"
	k1 "kabel1"
	vier "dasvierte"
	vierte "dasvierte"
	muenchentv "mnchentv"
	muenchen2 "mnchen2"
}
### tv-blacklist (string)
### sender die auf keinen fall gebraucht und geholt werden sollen
set tv-blacklist ""
### ist noch in der entwicklung

# tv-show-syntax (boolean 0/1)
# bei !tv die syntax anzeigen oder gleich die Hauptsender?
set tv-show-syntax 0

# tv-master (string)
# flags die nötig sind, um Einstellungen zu verändert oder das Script an/aus zuschalten.
set tv-master "+nmol-kdrq|+nmol-kdrq"

# tv-op (string)
# flags die nötig sind, um Sendungen/Sender zu verändern
set tv-op "+nmoavgfl-kdrq|+nmoavgfl-kdrq"

# tv-trigger (char)
set tv-trigger "!"

# tv-dynamic (digit) {New in 1.0.7}
# senderliste automatisch updaten 1 (aus 0)
set tv-dynamic 1

# tv-cachefile (string)
set tv-cachefile "/tmp/tv.cache"

### DU BRAUCHST HIER NUR WEITER GEHEN, WENN DU WEISST WAS DU TUST, ES KOMMT NUR NOCH PROGRAMM CODE  ###

package require http
if {[catch {package require tdom} cmsg]} {
	putlog "Das Tcl Packet 'tdom' wird benoetigt. Download: https://github.com/tdom/  Debian: apt-get install tdom"
	return
}


# wird bei cachetvdata jetzt geholt
if {![info exists ::tv(senderliste)]} {
	set ::tv(senderliste) {
	}
}

# Hier habe ich zB für meinen Bot meine eigene Sendertabelle als die große für alle, wenn jemand mag, verewige ich die Config hier auch gleich.
# Mail oder Posting im Forum hinterlassen.
if {$::username=="Newsflash"} {
	set global-tv-haupt "ard zdf sat1 pro7 kabel rtl rtl2 vox"
}
if {$::username=="pBot"} {set tv-trigger "."}

if {[llength [split ${global-tv-flood} :]]!=2} {
	putlog "TV-SCRIPT: Deine Flood einstellung sieht kaputt aus, stelle erstmal wieder default werte ein."
	set global-tv-flood 3:1800
}

foreach line [split $::tv(senderliste) \n] {
	set line [string tolower [string trim $line]]
	set line [split $line]
	set sender [join [lrange $line 0 end-1]]
	set id [lindex $line end]
	if {$sender == "" || $id == ""} { continue }
	set ::tv(sender_$sender) $id
}
proc pub:vxv:tv {n u h c t} {
	tvreply $n $u $h $c $t
}
proc pub:vxv:tvsearch {n u h c t} {
	tvsearch 0 $n $u $h $c $t
}
if {[binds cachetvdata]==""} {
	set m 0[rand 10]
	bind time - "$m 05 *" cachetvdata
	#bind time - "$m 07 *" cachetvdata
}

proc tvcheckrights {nick hand chan} {
	if {![channel get $chan tvmovie]} {return 0}
	set allow [channel get $chan tv-allow]
	set chanmodes [string trim [string tolower [channel get $chan tv-chanmodes]]]
	set userflags [string trim [string tolower [channel get $chan tv-userflags]]]
	if {$allow==0} {set allow ${::global-tv-allow}; channel set $chan tv-allow $allow}
	if {$chanmodes==""} {set chanmodes ${::global-tv-chanmodes}; channel set $chan tv-chanmodes $chanmodes}
	if {$userflags==""} {set userflags ${::global-tv-userflags}; channel set $chan tv-userflags $userflags}
	if {$allow==1} {return 1}
	if {$allow==2 || $allow>3} {
		set chanmode 0
		foreach chk $chanmodes {
			if {[catch {set $chk [is$chk $nick $chan]} msg]} {
				putlog "TV-SCRIPT: Hallo Admin, sieht so aus, als wenn du einen falschen chanmode in $chan configuriert hast!"
			} {if {[set $chk]} {set chanmode 1; break}}
		}
	}
	if {$allow>2} {
		if {![validuser $hand]} {set hand [nick2hand $nick]}
		if {[validuser $hand]} {
			set userflag [matchattr $hand $userflags $chan]
		} {set userflag 0}
	}
	switch -exact -- $allow {
		2 { return $chanmode }
		3 { return $userflag }
		4 { return [expr {$chanmode || $userflag}] }
		5 { return [expr {$chanmode && $userflag}] }
		default {putlog "TV-SCRIPT: Hallo Admin, sieht so aus, als wenn du einen falschen erlaubnis in $chan configuriert hast, erlaubt sind zahlen von 1-5!"}
	}
	return 0
}

if {![info exists ::tvfloodarray]} {array set ::tvfloodarray [list init 1]}
proc tvcheckflood {nick chan {incr 1}} {
	if {![channel get $chan tvmovie]} {return 0}
	set nick [string tolower $nick]
	set chan [string tolower $chan]
	set flood [string trim [string tolower [channel get $chan tv-flood]]]
	if {$flood!="" && [llength [split $flood :]]!=2 && [string is digit -strict [lindex [split $flood :] 0]] && [string is digit -strict [lindex [split $flood :] 1]]} {
		putlog "TV-SCRIPT: Hallo Admin, sieht so aus, als wenn du eine falsche flood einstellung in $chan configuriert hast!"
		set flood ""
	}
	if {$flood==""} {set flood ${::global-tv-flood}; channel set $chan tv-flood $flood}
	set count [lindex [split $flood :] 0]
	set time [lindex [split $flood :] 1]
	if {$count==0 || $time==0} {return 0}
	if {$incr>0} {
		if {![info exists ::tvfloodarray(n,$nick)]} {set nf 1} {set nf [expr {$incr+$::tvfloodarray(n,$nick)}]}
		if {![info exists ::tvfloodarray(c,$chan)]} {set cf 1} {
			if {$::tvfloodarray(c,$chan)<=$count+1} {
				set cf [expr {$incr+$::tvfloodarray(c,$chan)}]
			} {
				set cf $::tvfloodarray(c,$chan)
			}
		}
		set ::tvfloodarray(n,$nick) $nf
		set ::tvfloodarray(c,$chan) $cf
		if {[info command stimer]=="stimer"} {stimer $time [list tvcheckflood $nick $chan -1]} {utimer $time [list tvcheckflood $nick $chan -1]}
		if {$nf>$count || $cf>$count} {return 1} {return 0}
	} elseif {$incr<0} {
		if {![info exists ::tvfloodarray(n,$nick)]} {set nf -1} {set nf [expr {$incr+$::tvfloodarray(n,$nick)}]}
		if {![info exists ::tvfloodarray(c,$chan)]} {set cf -1} {set cf [expr {$incr+$::tvfloodarray(c,$chan)}]}
		if {$nf<1} {
			if {[info exists ::tvfloodarray(n,$nick)]} {unset ::tvfloodarray(n,$nick)}
		} {set ::tvfloodarray(n,$nick) $nf}
		if {$cf<1} {
			if {[info exists ::tvfloodarray(c,$chan)]} {unset ::tvfloodarray(c,$chan)}
		} {set ::tvfloodarray(c,$chan) $cf}
	} {
		putlog "WHO THE FUCK CALLED THE TVCHECKFLOOD PROC!!!?"
	}
}

proc savecache {} {
	puts [set f [open ${::tv-cachefile} w]]  "array set ::tvcache \[list [array get ::tvcache]\]";
	puts $f "array set ::tv \[list [array get ::tv sender*]\]";
	close $f
}
proc loadcache {} {
	array unset ::tv sender*
	array unset ::tvcache
	if {[file exists ${::tv-cachefile}]} {source ${::tv-cachefile}; return "cache loaded"} {return -1}
}
proc sorttvs {args} {
	### sortieren, haupt und kategorien zuerst
	set ::tvsorted [lsort -dict [array names ::tv sender_*]]
	set sorted [list]; set n 0
	foreach c [concat 0 [channels]] {
		if {$c=="0"} {
			set s ${::global-tv-haupt}
		} {
			set s [channel get $c tv-haupt]
		}
		set s [string tolower [string trim $s]]
		if {[string len $s]>0} {
			foreach k [split $s] {
				if {[lsearch -exact $sorted $k]==-1} {
					if {[set p [lsearch -exact $::tvsorted "sender_$k"]]!=-1} {
						lappend sorted $k
						set save [lindex $::tvsorted $p]
						set ::tvsorted [lreplace $::tvsorted $p $p]
						set ::tvsorted [linsert $::tvsorted $n $save]
						incr n
					}
				}
			}
		}
	}
	foreach c $::remindliste {
		set k [string tolower [string trim [lindex $c 1]]]
		if {[lsearch -exact $sorted $k]==-1} {
			if {[set p [lsearch -exact $::tvsorted "sender_$k"]]!=-1} {
				lappend sorted $k
				set save [lindex $::tvsorted $p]
				set ::tvsorted [lreplace $::tvsorted $p $p]
				set ::tvsorted [linsert $::tvsorted $n $save]
				incr n
			}
		}
	}
	###

}
proc cachetvdata {{args ""}} {
	if {![info exists ::tv(cacheindex)]} {
		putlog "Starting to cache TV data..."
		#sorttvs
		set ::tv(cacheindex) 0
	}
	sorttvs
	if {![info exists ::tvsorted]} {sorttvs}
	set index [lindex $::tvsorted $::tv(cacheindex)]
	if {$index == ""} {
		putlog "Okay, cached all data"
		# nochmal pruefen, falls nich noch dynamische dazu gekommen sind und anders sortiert
		# ::tv(cacheindex) muesste die anzahl enthalten
		set mis 0; set now [clock seconds]
		foreach name [array name ::tv sender_*] {
			set n1 [string map [list "sender_" ""] $name]
			set m 0
			if {![info exi ::tvupdate($n1)]} {
				putlog "missing $n1"
				set m 1
				incr mis
			} elseif {$now-$::tvupdate($n1)>21600} {
				putcmdlog "too old $n1"
				set m 1
				incr mis
			} {
				#			putcmdlog "is ok $n1; [duration [expr {$now-$::tvupdate($n1)}]]"
			}
			if {$m} {
				set id $::tv($name); set sendername $n1
				putloglev 1 * "Getting info for \"$sendername\"..."
				set ::tvcache($sendername) [tv_getinfo $id]
				set ::tvupdate($sendername) [clock seconds]
				putloglev 1 * "Got info (found [expr {[llength $::tvcache($sendername)] / 2}] entries)"
				if {[info command stimer]=="stimer"} {stimer 10 cachetvdata} {utimer 10 cachetvdata}
				return

			}
		}
		putcmdlog "missing $mis total"
		# richtiges ende :-)
		putcmdlog "$::tv(cacheindex)"
		unset ::tv(cacheindex)
		unset ::tvsorted
		return
	}
	if {[info exi ::tv($index)]} {
		set id $::tv($index)
		set sendername [string range $index 7 end]
		putloglev 1 * "Getting info for \"$sendername\"... ($::tv(cacheindex) / [llength [array names ::tv sender_*]])"
		set ::tvcache($sendername) [tv_getinfo $id]
		set ::tvupdate($sendername) [clock seconds]
		putloglev 1 * "Got info (found [expr {[llength $::tvcache($sendername)] / 2}] entries)"
	}
	incr ::tv(cacheindex)
	if {[info command stimer]=="stimer"} {stimer 10 cachetvdata} {utimer 10 cachetvdata}
	savecache
}
proc html2text {html} {
	regsub -all -- {(\\|\[|\])} $html {\\\1} text
	regsub -all -- "&#0{0,2}(\\d+);" $text {[format %c \1]} text
	set text [subst -novariables $text]
	return [string map [list {&iquest;} {¿} {&auml;} {ä} {&Auml;} {Ä} {&ouml;} ö {&Ouml;} {Ö} {&uuml;} ü {&Uuml;} {Ü} {&szlig;} {ß} \
		{</b>} {} {<b>} {} {&apos;} \' {&quot;} \" {&bdquo;} \" {&lsquo;} \` {&ndash;} {-} {&eacute;} {é} {&euml;} e \
		{&eagrave;} {è} {&iuml;} {ï} {&amp;} {&} {&nbsp;} { } {&gt;} {>} {&lt;} {<} {&diams;} {*} {&euro;} {€} \
		{&copy;} {©} {&trade;} {™} {&iexcl;} {¡} {&cent;} {¢} {&pound;} {£} {&sect;} {§} {&uml;} \" \
		{&plusmn;} {±} {&sup2;} {²} {&sup3;} {³} {&acute;} \' {&micro;} {µ} {&para;} {¶} {&middot;} {·} \
		{&frac14;} {¼} {&frac12;} {½} {&frac34;} {¾} {&bull;} {/} {&rsquo;} {’} {&rsquot;} {’} {&ldquo;} {`} \
		{&igrave;} {ì} {&Igrave;} {Ì} {&deg;} {°} {&Ccedil;} {Ç} {&atilde;} {ã} {&aring;} {å} {&Agrave;} {À} {&aelig;} {æ} {&acirc;} {â} {&aacute;} {á} \
		{&oacute;} {ó} {&ntilde;} {ñ} {&ldquo;} {“} {&laquo;} {«} {&icirc;} {î} {&iacute;} {í} {&hellip;} {…} {&egrave;} {è} {&ecirc;} {ê} {&Eacute;} {É} \
		{&ucirc;} {û} {&raquo;} {»} {&otilde;} {õ} {&Oslash;} {Ø} {&ocirc;} {ô} {&agrave;}  } {&Agrave;} {À}] $text]
}
proc tv_getinfo {id {noretry 0}} {
	set date [clock format [clock seconds] -format %Y-%m-%d]
	set url "http://www.tvmovie.de/TV_nach_Sendern.22.0.html?&date=$date"
	if {[catch {set token [http::geturl $url -query [http::formatQuery "senderid\[\]" $id] -timeout 30000]}]} {
		if {!$noretry} {timer 5 [list tv_getinfo $id 1]}
		return
	}
	set status [http::status $token]
	if {$status != "ok"} {
		error "HTTP-Error ($url): $status"
	}
	set data [http::data $token]
	http::cleanup $token
	if {${::tv-dynamic}==1} {
		#set newtv [list]
		if {$id==1} {array unset ::tv sender_*}
		#array set ::tv [list sender_muenchentv 376  sender_rtl2 6 sender_premiere5 235 sender_arena 410 sender_vierte 385  sender_premiere6 236 sender_premiere7 237 sender_muenchen2 403 sender_xxp 398 sender_nbc 172 sender_kabel1 8 sender_terranova 328 sender_spikatv 320 sender_bloomberg 273 sender_mtv2 179 sender_vivaplus 26 sender_vier 385 sender_atvplus 314 sender_tvnrw 209]
		foreach {fm num name} [regexp -all -inline {<option value="(\d+?)">(.+?)</option>} $data] {
			if {![string is digit -strict $num]} {
				putlog "TV: String isn't a digit $num for $name"
				catch {unset ::tv(cacheindex)}
				return
			}
			set name [html2text $name]
			regsub -all {[^a-zA-Z0-9]} $name "\\1" name
			set name [string tolower [string trim $name]]
			set name [string map [list "rtlii" "rtl2"] $name]
			set ::tv(sender_$name) $num
		}
	}
	if {![regexp -- {^.*?(Unter-Menue Anfang.*Unter-Menue Ende).*?$} $data "" data]} {
		error "First-Parse failed ($url)"
	}
	set found 0
	set result [list]
	regexp -- {^.*?Unter-Menue Anfang.*?<td valign="top".*?>(.*?)</td>.*?Unter-Menue Ende(.*)$} $data "" part1 data
	regexp -- {^.*?Unter-Menue Anfang.*?<td valign="top".*?>(.*?)</td>.*?Unter-Menue Ende(.*)$} $data "" part2 data
	regexp -- {^.*?Unter-Menue Anfang.*?<td valign="top".*?>(.*?)</td>.*?Unter-Menue Ende(.*)$} $data "" part3 data
	regexp -- {^.*?Unter-Menue Anfang.*?<td valign="top".*?>(.*?)</td>.*?Unter-Menue Ende(.*)$} $data "" part4 data
	regexp -- {^.*?Unter-Menue Anfang.*?<td valign="top".*?>(.*?)</td>.*?Unter-Menue Ende(.*)$} $data "" part5 data
	set data "$part1\n$part2\n$part3\n$part4\n$part5"
	while {[regexp -- {^.*?<span.*?>(.+?)</span>.*?<a .*?>(.+?)</a>(.+?)<br />(.*)$} $data "" time what descr data]} {
		set time [string trim $time]
		set what [html2text [string trim $what]]
		set descr [html2text [string trim $descr]]
		set descr [join [lrange [split $descr] 0 end-1]]
		putloglev 2 * "Got a new entry: \"$time\" \"$what\" \"$descr\""
		set hr [lindex [split $time :] 0]
		set min [lindex [split $time :] 1]
		set what [encrypt specialchar $what]
		set descr [encrypt specialchar $descr]
		if {[string index $hr 0] == 0 && [string index $hr 1] < 5} { incr hr 24 }
		set time $hr:$min
		lappend result $time $what $descr
		unset time; unset what; unset descr
	}
	return $result
}
proc striptext {text} {
	regsub -all -- "\002|\037|\026|\003(\\d{1,2})?(,\\d{1,2})?" $text "" text
	return $text
}
proc sendtvprg {chan {try 3}} {
	variable outnocolor
	variable outcolor
	variable outnicks
	variable outchan
	variable outupdate
	variable outtimer
	set now [clock seconds]
	set dotry 0
	if {[info exi outupdate($chan)] && [info exi outchan($chan)]} {
		if {$now-$outupdate($chan)>=1} {
			set o [list]
			foreach i $outchan($chan) {
				if {[string length "privmsg $chan :[join $o ", "], $i"]<375} {
					lappend o $i
				} {
					lappend o $i
					putmsg $chan [join $o ", "]; set o [list]
				}
			}
			if {$o!=[list]} {putmsg $chan [join $o ", "]; set o [list]}
			catch {unset outtimer($chan)}
			catch {unset outchan($chan)}
		} {set dotry 1}
	} {set dotry 1}
	if {$dotry} {
		incr try -1; if {$try>=1} {
			if {[info command stimer]=="stimer"} {stimer 1 [list sendtvprg $chan $try]} {utimer 1 [list sendtvprg $chan $try]}
		} {
			catch {unset outtimer($chan)}
			catch {unset outchan($chan)}
		}

	}
}
proc puttvprg {chan text} {
	set nocolor [list]; set color [list]; set nicks [list]
	set now [clock seconds]
	foreach c [split $chan ,] {
		set vert 1
		if {[validchan $c] && [channel get $c tv-design]=="horizontal"} {
			set vert 0
			variable outnocolor
			variable outcolor
			variable outnicks
			variable outchan
			variable outupdate
			variable outtimer
			if {![info exi outchan($c)]} {set outchan($c) [list]; }
			if {[validchan $c] && [string match *c* [lindex [split [getchanmode $c]] 0]]} {
				if {[lsearch -exact $outchan($c) [striptext $text]]==-1} {
					lappend outchan($c) [striptext $text]
				}
			} else {
				if {[lsearch -exact $outchan($c) $text]==-1} {
					lappend outchan($c) $text
				}
			}
			set outupdate($c) $now
			if {![info exists outtimer($c)]} {
				#set outtimer($c) [utimer 1 [list sendtvprg $c 3]]
				if {[info command stimer]=="stimer"} {
					set outtimer($c) [stimer 1 [list sendtvprg $c 3]]
				} {
					set outtimer($c) [utimer 1 [list sendtvprg $c 3]]
				}
			}

		} elseif {[validchan $c] && [string match *c* [lindex [split [getchanmode $c]] 0]]} {lappend nocolor $c} elseif {![validchan $c]} {lappend nicks $c} {lappend color $c}
		if {$vert} {
			if {$nocolor!=[list]} {
				putmsg [join $nocolor ,] [striptext $text]
			}
			if {$color!=[list]} {
				putmsg [join $color ,] $text
			}
			if {$nicks!=[list]} {
				putnotc [join $nicks ,] $text
			}
		}
	}
}
proc puttv {chan text} {
	set nocolor [list]; set color [list]; set nicks [list]
	foreach c [split $chan ,] {
		if {[validchan $c] && [string match *c* [lindex [split [getchanmode $c]] 0]]} {lappend nocolor $c} elseif {![validchan $c]} {lappend nicks $c} {lappend color $c}
	}
	if {$nocolor!=[list]} {
		putmsg [join $nocolor ,] [striptext $text]
	}
	if {$color!=[list]} {
		putmsg [join $color ,] $text
	}
	if {$nicks!=[list]} {
		putnotc [join $nicks ,] $text
	}
}
bind pub - "${::tv-trigger}tv" tvreply
#bind pub - "${::tv-trigger}tvsearch" "tvsearch 1"
#bind pub - "${::tv-trigger}tvsearchall" "tvsearch 0"
setudef flag tvmovie
setudef int tv-allow
setudef str tv-chanmodes
setudef str tv-userflags
setudef str tv-flood
setudef str tv-design
setudef str tv-haupt

proc tvsearch {nurhaupt n u h c t} {
	if {[lsearch [channel info $c] -tvmovie]!=-1} {return}
	if {![tvcheckrights $n $h $c]} {putlog "TV-SCRIPT: $n ($h) hat nich genug Rechte in $c"; return}
	set flood [tvcheckflood $n $c]
	if {$flood} {set d $n} {set d $c}
	set maske [string trim $t]
	if {$maske == ""} {
		puttv $d "Syntax: \002$::lastbind <suchmaske>\002"; return
	}
	if {![regexp -- {^[äöüÄÖÜßa-zA-Z0-9\+ \-]+$} $maske]} {
		puttv $d "Please use only A-Z and 0-9, no wildcards. Thanks."; return
	}
	if {[string length $maske] < 3} {
		puttv $d "<mask> must have at least 3 chars!"; return
	}
	http::config -useragent {Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.8.0.4) Gecko/20060508 Firefox/1.5.0.4}
	set url "http://www.tvmovie.de/Suchergebnisse_TV.211.0.html"
	set maske [string map [list " " "%"] $maske]
	if {$nurhaupt} {
		set tok [http::geturl $url -query [http::formatQuery "allgemein\[titel\]" $maske no_cache 1 "tv\[sender\]" A] -timeout 30000]
	} {
		set tok [http::geturl $url -query [http::formatQuery "allgemein\[titel\]" $maske no_cache 1] -timeout 30000]
	}
	set status [http::status $tok]
	if {$status != "ok"} {
		error "HTTP-Error ($url): $status"
	}
	set data [http::data $tok]
	http::cleanup $tok
	if {![regexp -- {^.*?<span .*?>(\d+) Treffer</span>(.*)$} $data "" found data]} {
		error "Search-Parse failed ($url)"
	}
	if {!$found} {
		if {$nurhaupt} {
			puttv $d "Nothing found on main stations. Expanding search..."; after 0 [list tvsearch 0 $n $u $h $c $t]; return
		} {
			puttv $d "Nothing found."; return
		}
	}
	set c 0
	while {$c < 6 && [regexp -nocase -- {^.*?<table(.*?)</table>.*?<table(.*?)</table>.*?Trennlinie(.*)$} $data "" t1 t2 data]} {
		regexp -- {^.*?<td(.*?)</td>.*?<td(.*?)</td>.*?<td(.*?)</td>} $t1 "" t11 t12 t13
		regexp -- {^.*?<td(.*?)</td>.*?<td(.*?)</td>.*?<td(.*?)</td>} $t2 "" t21 t22 t23
		regexp -nocase -- {^.*?<img src=.*?>(.*?)<img src=.*?<a.*?>(.*?)</a><img src=.*?>(.*?)Uhr} $t12 "" tag sender time
		regexp -- {^.*?<a href=.*?>(.*?)</a>.*?<span.*?>(.*?)</span>} $t22 "" what descr
		set tag [string trim $tag]
		set sender [string tolower [string map {" " ""} [string trim $sender]]]
		set time [string trim $time]
		set what [html2text [string trim $what]]
		set descr [html2text [string trim $descr]]
		putloglev 2 * "Found a search result: \"$tag\" \"$time\" \"$sender\" \"$what\" \"$descr\""
		puttvprg $d "\002$tag $time\002 ($sender) \002$what\002 \[$descr\]"
		incr c
	}
	if {$c == 6} {
		if {$nurhaupt} {
			puttvprg $d "Für weitere Ergebnisse: \037http://www.tvmovie.de/Suchergebnisse_TV.211.0.html?[http::formatQuery "allgemein\[titel\]" "$maske" "no_cache" "1" "tv\[sender\]" "A"]\037 "
		} {
			puttvprg $d "Für weitere Ergebnisse: \037http://www.tvmovie.de/Suchergebnisse_TV.211.0.html?[http::formatQuery "allgemein\[titel\]" "$maske" "no_cache" "1"]\037 "
		}
	}
}

proc tvreply {n u h c t} {
	set arg1 [lindex [split $t] 0]
	set arg2 [lindex [split $t] 1]
	if {[matchattr $h ${::tv-master} $c] && $arg1=="on"} {puttv $n "TV-Script eingeschaltet."; channel set $c +tvmovie; return}
	if {[matchattr $h ${::tv-master} $c] && $arg1=="off"} {puttv $n "TV-Script ausgeschaltet."; channel set $c -tvmovie; return}
	if {[lsearch [channel info $c] -tvmovie]!=-1 && $arg1!="help" && $arg1=="hilfe" && $arg1!="h"} {return}
	if {![tvcheckrights $n $h $c] && $arg1!="help" && $arg1=="hilfe" && $arg1!="h"} {putlog "TV-SCRIPT: $n ($h) hat nich genug Rechte in $c"; return}
	set flood [tvcheckflood $n $c]
	if {$flood} {set d $n} {set d $c}
	if {$arg1 == ""} {
		if {${::tv-show-syntax}} {
			puttv $d "Syntax: \002$::lastbind \[sender\] \[zeit\] \[anzahl\]\002"; return
		}
	} elseif {($arg1=="help" || $arg1=="hilfe" || $arg1=="h")} {
		putlog "${::tv-trigger}TV-Hilfe von $n!$u ($h) in $c"
		if {![channel get $c tvmovie]} {
			if {[matchattr $h ${::tv-master} $c]} {
				puttv $n "TV-SCRIPT: Das TV-Script ist nich aktiviert in $c. Schalt es doch mit '${::tv-trigger}tv on' ein."
				putlog "TV-SCRIPT: $n ($h) $c hat das TV Script nicht aktiviert."
			} {
				puttv $n "TV-SCRIPT: Das TV-Script ist nich aktiviert in $c. Bitte einen Admin es anzuschalten."
				putlog "TV-SCRIPT: $n ($h) $c hat das TV Script nicht aktiviert."
			}
			return
		}
		if {![tvcheckrights $n $h $c]} {
			puttv $n "TV-SCRIPT: Du hast nich genug Rechte in $c"
			putlog "TV-SCRIPT: $n ($h) hat nich genug Rechte in $c"
			return
		}
		puttv $n "Hilfe für das TV-Script:"
		if {[matchattr $h ${::tv-master} $c]} {
			puttv $n "${::tv-trigger}tv on/off                    (de)aktiviert das script in diesen channel."
			puttv $n "${::tv-trigger}tv get                       Zeigt die aktuellen Rechte, Flood-Settings, Hauptsender und Design"
			puttv $n "${::tv-trigger}tv set <name> <value>        möglich allow, chanmodes, userflags, design, flood, haupt und design"
		}
		if {[matchattr $h ${::tv-op} $c]} {
			puttv $n "${::tv-trigger}tvlist                       Zeigt die Erinnerungsliste"
			puttv $n "${::tv-trigger}tvadd <sender> <suche>       Fügt einen Suchbegriff zur Suchliste hinzu"
			puttv $n "${::tv-trigger}tvdel <sender> <suche>       siehe drüber nur entfernen ;)"
			puttv $n "${::tv-trigger}tvhaupt                      Zeigt die Hauptsender an"
			puttv $n "${::tv-trigger}addhaupt <sender>            Fügt einen Sender zur Hauptsender Liste zu"
			puttv $n "${::tv-trigger}delhaupt <sender>            und das gleiche wieder nur entfernen"

		}
		puttv $n "${::tv-trigger}tv \[zeit\] \[sender\] \[anzahl\]  Zeigt per default die Hauptsender von jetzt an"
		#		puttv $n "${::tv-trigger}tvsearch <suchbegriff>       Sucht nach Hauptsendern nach dem Suchbegriff"
		#		puttv $n "${::tv-trigger}tvsearchall <suchbegriff>    Sucht nach Sendern nach dem Suchbegriff"

		return
	} elseif {[matchattr $h ${::tv-op} $c] && ($arg1=="reload" || $arg1=="r")} {
		cachetvdata
		return
	} elseif {[matchattr $h ${::tv-op} $c] && ($arg1=="live" || $arg1=="li")} {
		# liveticker
		return
	} elseif {[matchattr $h ${::tv-op} $c] && ($arg1=="list" || $arg1=="l")} {
		# listen (hauptsender, erinnerungen, usw)
		putcmdlog "tv list"
		switch -exact -- $arg2 {
			help {}
			h - ha - haupt {}
			k - kat - d - descr {}
			default {
				putcmdlog "default"
				puttv $n "Senderliste: ([llength [array name ::tv sender_*]] total)"
				set txt "NOTICE $n :"
				foreach n1 [lsort -dict [array name ::tv sender_*]] {
					set n1 [string map [list "sender_" ""] $n1]
					append txt "$n1, "
					if {[string len $txt]>400} {
						set txt [string range $txt 0 end-2]
						puthelp $txt
						set txt "NOTICE $n :"
					}
				}
				if { $txt != "NOTICE $n :" } {
					set txt [string range $txt 0 end-2]
					puthelp $txt
				}
			}
		}
		return
	} elseif {[matchattr $h ${::tv-op} $c] && ($arg1=="search" || $arg1=="s")} {
		# suche
		switch -exact -- $arg2 {
			k - kat - d - descr {
				#beschreibung
			}
			default {
				#name der sendung
			}
		}
		return
	} elseif {[matchattr $h ${::tv-op} $c] && ($arg1=="add" || $arg1=="a")} {
		# hinzufügen
		return
	} elseif {[matchattr $h ${::tv-op} $c] && ($arg1=="del" || $arg1=="d")} {
		# entfernen
		return
	} elseif {[matchattr $h ${::tv-op} $c] && ($arg1=="name" || $arg1=="n")} {
		# ...
		return
	} elseif {[matchattr $h ${::tv-op} $c] && ($arg1=="kat" || $arg1=="descr" || $arg1=="k" || $arg1=="d")} {
		# kategorien / beschreibungen (die in eckigen klammern)
		return
	} elseif {[matchattr $h ${::tv-op} $c] && ($arg1=="sub" || $arg1=="unter" || $arg1=="untertitel")} {
		# untertitel (die in runden klammern)
		return
	} elseif {[matchattr $h ${::tv-op} $c] && ($arg1=="group" || $arg1=="g")} {
		# gruppierungen
		switch -exact -- $arg2 {
			h - help {}
			l - list {puttv $d "Im moment gibt es nur 'haupt' und 'sport'.. (veraltet)"}
			a - add {}
			d - del {}
			s - show {}
		}
		#		puttv $d "Benötigt Rechte: [join $Allow $join], Flood-Protection $Flood, Hauptsender: $haupt"
		return
	} elseif {[matchattr $h ${::tv-master} $c] && $arg1 == "set"} {
		# einstellungen
		set value [lindex [split $t] 2]
		set valueall [join [lrange [split $t] 2 end]]
		switch -exact -- $arg2 {
			allow {if {[string is digit -strict $value] && $value>=0 && $value<=5} {channel set $c tv-allow $value; puttv $d "Einstellung übernommen."} {puttv $d "Falscher Wert, erlaubt ist: 0=Default, 1=Alle, 2=Chanmode, 3=Userflag, 4=Chanmode || Userflag, 5=Chanmode && Userflag, momentan is: [channel get $c tv-allow]."}}
			chanmodes {
				if {$value==""} {puttv $d "Falscher Wert, erlaubt ist: op halfop voice, momentan is: [channel get $c tv-chanmodes]."; return}
				foreach val [split [string tolower $valueall]] {if {[lsearch -exact [list voice halfop op] $val]!=-1} {lappend ok $val} {lappend notok $val}}
				if {[info exists ok]} {lappend txt "Folgende Einstellung übernommen: [join $ok]"; channel set $c tv-chanmodes [join $ok]}
				if {[info exists notok]} {lappend txt "Folgende Einstellung verworfen: [join $notok]"}
				if {[info exists txt]} {puttv $d "[join $txt ", "]."}
			}
			userflags {
				if {$value==""} {puttv $d "Falscher Wert, erlaubt ist: nmo+v-kdrq|n+mov-kdrq, momentan is: [channel get $c tv-userflags]."; return}
				foreach val [split [string tolower $valueall] ""] {if {![string match "\[+-|a-zA-Z0-9\]" $val]} {set notok 1; break}}
				if {![info exists notok]} {channel set $c tv-userflags $value; puttv $d "Einstellung übernommen."} {puttv $d "Falscher Wert, erlaubt ist: nmo+v-kdrq|n+mov-kdrq, momentan is: [channel get $c tv-userflags]."; return}
			}
			design {
				if {[channel get $c tv-design]==""} {channel set $c tv-design ${::global-tv-design} }
				if {$value==""} {puttv $d "Falscher Wert, erlaubt ist: vertikal list horizontal flat tile, momentan is: [channel get $c tv-design]."; return}
				if {$value=="list"} {set value vertikal}; if {$value=="tile" || $value=="flat"} {set value horizontal}
				if {$value=="vertikal" || $value=="horizontal"} {channel set $c tv-design $value; puttv $d "Einstellung übernommen."} {puttv $d "Falscher Wert, erlaubt ist: vertikal flat list horizontal tile, momentan is: [channel get $c tv-design]."; return}
			}
			flood {
				if {$value==""} {puttv $d "Falscher Wert, erlaubt ist: 3:600 (anzahl:zeit in seks), momentan is: [channel get $c tv-flood]."; return}
				if {[llength [split $value :]]!=2} {puttv $d "Falscher Wert, erlaubt ist: 3:600 (anzahl:zeit in seks), momentan is: [channel get $c tv-flood]."; return}
				if {[string is digit -strict [lindex [split $value :] 0]] && [string is digit -strict [lindex [split $value :] 1]]} {channel set $c tv-flood $value; puttv $d "Einstellung übernommen."} {puttv $d "Falscher Wert, erlaubt ist: 3:600 (anzahl:zeit in seks), momentan is: [channel get $c tv-flood]."}
			}
			haupt {
				if {$value==""} {puttv $d "Falscher Wert, erlaubt ist: ard zdf rtl sat1 pro7, momentan is: [channel get $c tv-haupt]."; return}
				foreach val [split [string tolower $valueall]] {
					set senderid [lindex [array names ::tv sender_$val] 0]
					if {$senderid == ""} {lappend notok $val} {lappend ok $val}
				}
				if {[info exists ok]} {lappend txt "Folgende Sender übernommen: [join $ok]"; channel set $c tv-haupt [join $ok]}
				if {[info exists notok]} {lappend txt "Folgende Sender verworfen: [join $notok]"}
				if {[info exists txt]} {puttv $d "[join $txt ", "]."}
			}
			default {
				puttv $d "Falsches Setting: $::lastbind set <allow|chanmodes|userflags|flood|haupt|design> <value>"
			}
		}
		return
	} elseif {[matchattr $h ${::tv-master} $c] && $arg1 == "get"} {

		if {[channel get $c tv-design]==""} {channel set $c tv-design ${::global-tv-design} }
		set allow [channel get $c tv-allow]
		set design [channel get $c tv-design]
		set chanmodes [string trim [string tolower [channel get $c tv-chanmodes]]]
		set userflags [string trim [string tolower [channel get $c tv-userflags]]]
		set haupt [string trim [string tolower [channel get $c tv-haupt]]]
		if {$haupt==""} {set haupt ${::global-tv-haupt}; channel set $c tv-haupt $haupt}
		if {$allow==0} {set allow ${::global-tv-allow}; channel set $c tv-allow $allow}
		if {$chanmodes==""} {set chanmodes ${::global-tv-chanmodes}; channel set $c tv-chanmodes $chanmodes}
		if {$userflags==""} {set userflags ${::global-tv-userflags}; channel set $c tv-userflags $userflags}
		set flood [string trim [string tolower [channel get $c tv-flood]]]
		if {$flood!="" && [llength [split $flood :]]!=2 && [string is digit -strict [lindex [split $flood :] 0]] && [string is digit -strict [lindex [split $flood :] 1]]} {
			putlog "TV-SCRIPT: Hallo Admin, sieht so aus, als wenn du eine falsche flood einstellung in $c configuriert hast!"
			set flood ""
		}
		if {$allow==1} {lappend Allow Keine}
		if {$allow==2 || $allow>3} {lappend Allow "Channel modes \"$chanmodes\""}
		if {$allow>2} {lappend Allow "Userflags \"$userflags\""}
		if {$allow==4} {set join " || "} elseif {$allow==5} {set join " && "} {set join ", "}
		if {$flood==""} {set flood ${::global-tv-flood}; channel set $c tv-flood $flood}
		set count [lindex [split $flood :] 0]
		set time [lindex [split $flood :] 1]
		if {$count==0 || $time==0} {set Flood "aus"} {
			set Flood "auf $count benutzungen in [string map [list hours stunden hour stunde minutes minuten seconds sekunden second sekunde] [duration $time]]"
		}
		if {![channel get $c tvmovie]} {
			puttv $d "TV Script ist ausgeschaltet, Benötigt Rechte: [join $Allow $join], Flood-Protection $Flood, Hauptsender: $haupt, Design: $design"
		} {
			puttv $d "Benötigt Rechte: [join $Allow $join], Flood-Protection $Flood, Hauptsender: $haupt, Design: $design"
		}
		return
	}
	if {![channel get $c tvmovie]} {
		putlog "TV-SCRIPT: ist nicht aktiviert in $c."
		return
	}
	if {$arg1==""} {
		tvreply2 $n $u $h $c "jetzt" $flood
		return
	}
	set fZeit [list]; set fSender [list]; set fNum [list]; set fLast [list];
	set lZeit [list]; set lSender [list]; set lNum [list]; set lLast [list];
	set nZeit [list]; set nSender [list]; set nNum [list]; set nLast [list];
	set Next 0; set clear 0
	foreach arg [split $t] {
		incr Next; set nextarg [lindex [split $t] $Next]
		if {[regexp -- {^0{0,1}(\d{1,2}):0{0,1}(\d{1,2})$} $arg "" h m]} {
			lappend fZeit "$h:$m"
			lappend fLast Zeit
		} elseif {[regexp -- {^0{0,1}(\d{1,2})$} $arg "" arg1]} {
			if {$arg1>9} {
				lappend fZeit "$arg1:0"
				lappend fLast Zeit
			} {
				lappend fNum $arg1
				lappend fLast Num
			}
		} elseif {[string match -nocase *jetzt*gleich* $arg] || [string equal -nocase jg $arg]} {
			lappend fNum 1
			lappend fLast Num
			lappend n$fLast [set f$fLast]
			lappend nLast $fLast
			set f$fLast [list]
			set fLast [list]
			set hour [clock format [clock seconds] -format %H]; if {[string index $hour 0] == "0"} { set hour [string index $hour 1] }
			set min  [clock format [clock seconds] -format %M]; if {[string index $min 0] == "0"}  { set min  [string index $min 1] }
			lappend fLast Zeit
			lappend fZeit "$hour:$min"
			lappend n$fLast [set f$fLast]
			lappend nLast $fLast
			set f$fLast [list]
			set fLast [list]
			if {$nZeit==[list]} {set nZeit "jetzt"}
			if {$nSender==[list]} {set nSender $lSender}
			if {$nSender==[list]} {set nSender "haupt"}
			if {$nNum==[list]} {set nNum $lNum}
			if {$nNum==[list]} {
				set nNum 2
				if {0} {
					# einfügen das senderlisten geprüft werden
				} elseif {[set p [lsearch -exact ${::global-tv-kategorie} [string tolower $nSender]]] && $p % 2 == 0} {
					# kategorie gefunden
					set ks [lindex ${::global-tv-kategorie} [expr {$p+1}]]
					if {[llength $ks]==1} {set nNum 3} elseif {[llength $ks]==2} {set nNum 2} {set nNum 1}
				} elseif {[lsearch -exact [string tolower $nSender] "haupt"]>=0} {
					set nNum 1
				} elseif {[llength $nSender]==1} {
					set nNum 3
				} elseif {[llength $nSender]==2} {
					set nNum 2
				} else {
					set nNum 1
				}
			}
			foreach Sender $nSender {
				tvreply2 $n $u $h $c "$nZeit $Sender" $flood $nNum
			}
			set lZeit $nZeit; set nZeit [list]
			set lSender $nSender; set nSender [list]
			set lNum $nNum; set nNum [list]
			set lLast $nLast; set nLast [list]
			set f$fLast [list]
			set fLast [list]
			lappend fNum 2
			lappend fLast Num
			lappend n$fLast [set f$fLast]
			lappend nLast $fLast
			set f$fLast [list]
			set fLast [list]
			lappend fZeit "$hour:$min"
			lappend fLast Zeit
		} elseif {[string match -nocase *jetz* $arg]} {
			set hour [clock format [clock seconds] -format %H]; if {[string index $hour 0] == "0"} { set hour [string index $hour 1] }
			set min  [clock format [clock seconds] -format %M]; if {[string index $min 0] == "0"}  { set min  [string index $min 1] }
			lappend fZeit "$hour:$min"
			lappend fLast Zeit
		} else {
			lappend fSender $arg
			lappend fLast Sender
		}
		if {$fLast!="Sender" && [llength [lsort -unique $nLast]]>2} {set clear 1}
		if {$fLast=="Zeit" && [lsearch -exact $nLast $fLast]>=0} {set clear 1}
		if {$fLast=="Num" && [llength [lsearch -all $nLast $fLast]]>1} {set clear 1}
		if {[llength $nNum]>1} {set clear 1}
		if {$clear} {
			if {[llength $nNum]>1} {
				set nZeit [lindex $nNum 0]:0
				set nNum [lindex $nNum 1]
			}
			if {$nZeit==[list]} {set nZeit "jetzt"}
			if {$nSender==[list]} {set nSender $lSender}
			if {$nSender==[list]} {set nSender "haupt"}
			if {$nNum==[list]} {set nNum $lNum}
			if {$nNum==[list]} {
				set nNum 2
				if {[lsearch -exact [string tolower $nSender] "haupt"]>=0} {
					set nNum 1
				} elseif {[set p [lsearch -exact ${::global-tv-kategorie} [string tolower $nSender]]] && $p % 2 == 0} {
					# kategorie gefunden
					set ks [lindex ${::global-tv-kategorie} [expr {$p+1}]]
					if {[llength $ks]==1} {set nNum 3} elseif {[llength $ks]==2} {set nNum 2} {set nNum 1}
				} elseif {[llength $nSender]==1} {
					set nNum 3
				} elseif {[llength $nSender]==2} {
					set nNum 2
				} else {
					set nNum 1
				}
			}
			set clear 0
			foreach Sender $nSender {
				tvreply2 $n $u $h $c "$nZeit $Sender" $flood $nNum
			}
			set lZeit $nZeit; set nZeit [list]
			set lSender $nSender; set nSender [list]
			set lNum $nNum; set nNum [list]
			set lLast $nLast; set nLast [list]
			lappend n$fLast [set f$fLast]
			lappend nLast $fLast
			set f$fLast [list]
			set fLast [list]
		} {
			lappend n$fLast [set f$fLast]
			lappend nLast $fLast
			set f$fLast [list]
			set fLast [list]
		}
	}
	if {[llength $nNum]>1} {
		set nZeit [lindex $nNum 0]:0
		set nNum [lindex $nNum 1]
	}
	if {$nZeit==[list]} {set nZeit jetzt}
	if {$nSender==[list]} {set nSender $lSender}
	if {$nSender==[list]} {set nSender "haupt"}
	if {$nNum==[list]} {set nNum $lNum}
	if {$nNum==[list]} {
		set nNum 2
		if {0} {
			# hier auch prüfen
		} elseif {[set p [lsearch -exact ${::global-tv-kategorie} [string tolower $nSender]]] && $p % 2 == 0} {
			# kategorie gefunden
			set ks [lindex ${::global-tv-kategorie} [expr {$p+1}]]
			if {[llength $ks]==1} {set nNum 3} elseif {[llength $ks]==2} {set nNum 2} {set nNum 1}
		} elseif {[lsearch -exact [string tolower $nSender] "haupt"]>=0} {
			set nNum 1
		} elseif {[llength $nSender]==1} {
			set nNum 3
		} elseif {[llength $nSender]==2} {
			set nNum 2
		} else {
			set nNum 1
		}
	}
	set clear 0
	foreach Sender $nSender {
		tvreply2 $n $u $h $c "$nZeit $Sender" $flood $nNum
	}
	set lZeit $nZeit; set nZeit [list]
	set lSender $nSender; set nSender [list]
	set lNum $nNum; set nNum [list]
	set lLast $nLast; set nLast [list]

}
proc tvreply2 {n u h c t flood {num -1}} {
	if {[info exi ::double-help] && ${::double-help}==1} {set restore 1; set ::double-help 0} {set restore 0}
	set arg1 [lindex [split $t] 0]
	set arg2 [lindex [split $t] 1]
	if {[regexp -- {^0{0,1}(\d{1,2})$} $arg1 "" arg1]} {
		set hour $arg1
		set min 0
		set sender $arg2
	} elseif {[regexp -- {^0{0,1}(\d{1,2}):0{0,1}(\d{1,2})$} $arg1 "" h m]} {
		set hour $h
		set min $m
		set sender $arg2
	} elseif {[regexp -- {^0{0,1}(\d{1,2})$} $arg2 "" arg2]} {
		set hour $arg2
		set min 0
		set sender $arg1
	} elseif {[regexp -- {^0{0,1}(\d{1,2}):0{0,1}(\d{1,2})$} $arg2 "" h m]} {
		set hour $h
		set min $m
		set sender $arg1
	} elseif {[string match -nocase *jetz* $arg1]} {
		set sender $arg2
		set hour [clock format [clock seconds] -format %H]
		if {[string index $hour 0] == "0"} { set hour [string index $hour 1] }
		set min [clock format [clock seconds] -format %M]
		if {[string index $min 0] == "0"} { set min [string index $min 1] }
	} elseif {[string match -nocase *jetz* $arg2]} {
		set sender $arg1
		set hour [clock format [clock seconds] -format %H]
		if {[string index $hour 0] == "0"} { set hour [string index $hour 1] }
		set min [clock format [clock seconds] -format %M]
		if {[string index $min 0] == "0"} { set min [string index $min 1] }
	} else {
		set sender $arg1
		set hour [clock format [clock seconds] -format %H]
		if {[string index $hour 0] == "0"} { set hour [string index $hour 1] }
		set min [clock format [clock seconds] -format %M]
		if {[string index $min 0] == "0"} { set min [string index $min 1] }
	}
	if {$sender == ""} {
		set sender "haupt"
	}
	if {$hour < 5} { incr hour 24 }
	set sender [string tolower $sender]
	if {$flood} {
		showtvdata $n $c $hour $min $sender $num
	} {
		showtvdata $c $c $hour $min $sender $num
	}
	if {$restore==1} {set ::double-help 1}
}
proc showtvdata {dest chan h m sender {howmuch -1}} {
	if {$sender == "2015"} {
		showtvdata $dest $chan 20 15 haupt 1
		return
	}
	if {$sender == "sport"} {
		if {$howmuch==-1} {
			showtvdata $dest $chan $h $m eurosport 2
			showtvdata $dest $chan $h $m sport1 2
		} {
			showtvdata $dest $chan $h $m eurosport $howmuch
			showtvdata $dest $chan $h $m sport1 $howmuch
		}
		return
	}
	if {$sender == "haupt"} {
		set haupt [string trim [string tolower [channel get $chan tv-haupt]]]
		if {$haupt==""} {set haupt ${::global-tv-haupt}; channel set $chan tv-haupt $haupt}
		foreach sender $haupt {
			if {$howmuch==-1} {
				showtvdata $dest $chan $h $m $sender 1
			} {
				showtvdata $dest $chan $h $m $sender $howmuch
			}
		}
		return
	}
	if {$sender == "haupt2"} {
		set haupt [string trim [string tolower [channel get $chan tv-haupt]]]
		if {$haupt==""} {set haupt ${::global-tv-haupt}; channel set $chan tv-haupt $haupt}
		foreach sender $haupt {
			if {$howmuch==-1} {
				showtvdata $dest $chan $h $m $sender 2
			} {
				showtvdata $dest $chan $h $m $sender $howmuch
			}
		}
		return
	}
	set sender [string map {" " *} $sender]
	set senderid [lindex [array names ::tv sender_$sender] 0]
	if {$senderid == ""} {
		if {[set p [lsearch -exact ${::global-tv-kategorie} $sender]] && $p % 2 == 0} {
			# kategorie gefunden
			set ks [lindex ${::global-tv-kategorie} [expr {$p+1}]]
			foreach s $ks {showtvdata $dest $chan $h $m $s $howmuch}
			return
		} {
			puttv $dest "Sender nicht gefunden."; return
		}
	}
	set sendername [string range $senderid 7 end]
	if {![info exists ::tvcache($sendername)]} {puttv $dest "Sender nicht gefunden."; return}
	set sttime [unixtime]
	if {$howmuch==-1} {set howmuch 3}
	for {set i 0} {$i < [llength $::tvcache($sendername)]} {incr i 3} {
		if  {[unixtime]-$sttime>10} {break}
		set time [lindex $::tvcache($sendername) $i]
		if {[string index $time 0] == "0"} { set hour [string index $time 1] } else { set hour [string range $time 0 1] }
		set min [string range $time 3 4]
		if {[string index $hour 0] == "0"} { set hour [string index $hour 1] }
		if {[string index $min 0] == "0"} { set min [string index $min 1] }
		if {$hour > $h || $hour == $h && $min >= $m} {
			if {$hour != $h || $min != $m} {incr i -3}
			set nums 0
			while {$nums < $howmuch && [unixtime]-$sttime<=10} {
				set time [lindex $::tvcache($sendername) $i]; incr i
				if {[string index $time 0] == "0"} { set hour [string index $time 1] } else { set hour [string range $time 0 1] }
				set min [string range $time 3 4]
				if {$hour > 23} { incr hour -24 }
				if {[string length $hour]==1} {set hour 0$hour}
				set time $hour:$min
				set what [decrypt specialchar [lindex $::tvcache($sendername) $i]]; incr i
				set descr [decrypt specialchar [lindex $::tvcache($sendername) $i]]; incr i
				if {[regexp {^\s*?(\(.*\))(.*)$} $descr "" temp descr]} { set what "$what $temp"; set descr [string trim $descr] }
				if {$time != "" && $time != ":"} {
					if {$descr!=""} {
						puttvprg $dest "\002$time\002 ($sendername) \002$what\002 \[$descr\]"
					} {
						puttvprg $dest "\002$time\002 ($sendername) \002$what\002"
					}
					incr nums
				}
			}
			break
		}
	}
	if {![info exists nums]} {
		set i [expr {[llength $::tvcache($sendername)]-3}]
		set time [lindex $::tvcache($sendername) $i]; incr i
		if {[string index $time 0] == "0"} { set hour [string index $time 1] } else { set hour [string range $time 0 1] }
		set min [string range $time 3 4]
		if {$hour > 23} { incr hour -24 }
		set time $hour:$min
		set what [decrypt specialchar [lindex $::tvcache($sendername) $i]]; incr i
		set descr [decrypt specialchar [lindex $::tvcache($sendername) $i]]; incr i
		if {[regexp {^\s*?(\(.*\))(.*)$} $descr "" temp descr]} { set what "$what $temp"; set descr [string trim $descr] }
		if {$time != "" && $time != ":"} {
			if {$descr!=""} {
				puttvprg $dest "\002$time\002 ($sendername) \002$what\002 \[$descr\]"
			} {
				puttvprg $dest "\002$time\002 ($sendername) \002$what\002"
			}
		}
	}
}
bind time - "?0 *" chktimetv
bind time - "?5 *" chktimetv

proc chktimetv args {
	foreach item $::remindliste {
		foreach {ch s m} $item {
			remindtv $ch $s $m
		}
	}
	return
	set total [llength [array names ::tv sender_*]]
	if {[info command stimer]=="stimer"} {
		set timer [stimerexists cachetvdata]
		if {[info exists ::tv(cacheindex)]} {
			if {$timer=="" && $::tv(cacheindex)<$total} {stimer 15 cachetvdata}
		}
	} {
		set timer [utimerexists cachetvdata]
		if {[info exists ::tv(cacheindex)]} {
			if {$timer=="" && $::tv(cacheindex)<$total} {utimer 15 cachetvdata}
		}
	}
}
bind pub - ${::tv-trigger}tvhelp tvhelp
bind pub - ${::tv-trigger}tvhilfe tvhelp
proc tvhelp {n u h c t} {
	tvreply $n $u $h $c "help"
}
bind pub - ${::tv-trigger}addhaupt addhaupttv
bind pub - ${::tv-trigger}delhaupt delhaupttv
bind pub - ${::tv-trigger}tvhaupt listhaupttv
proc addhaupttv {n u h c t} {
	if {[lsearch [channel info $c] -tvmovie]!=-1} {return}
	if {![tvcheckrights $n $h $c] || ![matchattr $h ${::tv-op} $c]} {putlog "TV-SCRIPT: $n ($h) hat nich genug Rechte in $c"; return}
	set flood [tvcheckflood $n $c]
	if {$flood} {set d $n} {set d $c}
	set sender [lindex [split $t] 0]
	if {[validchan $sender]} {
		set dc [string tolower $sender]
		set sender [lindex [split $t] 1]
		set sendung [join [lrange [split $t] 2 end]]
	} {
		set dc [string tolower $c]
		set sendung [join [lrange [split $t] 1 end]]
	}
	if {$sender==""} {
		puttv $d "Syntax: \002$::lastbind <sender>"; return
	}
	set sender [string map {" " *} $sender]
	set senderid [lindex [array names ::tv sender_$sender] 0]
	if {$senderid == ""} {
		puttv $d "Sender nicht gefunden."; return
	}
	set sendername [string range $senderid 7 end]
	set haupt [string trim [string tolower [channel get $c tv-haupt]]]
	if {$haupt==""} {set haupt ${::global-tv-haupt}; channel set $c tv-haupt $haupt}
	if {[lsearch -exact [split $haupt] $sendername]==-1} {
		set haupt [split $haupt]
		lappend haupt $sendername
		set haupt [join $haupt]
		channel set $c tv-haupt $haupt
		puttv $d "Sender zu den Hauptsendern hinzugefügt."
	} {
		puttv $d "Sender ist bereits unter den Hauptsender."
	}
}
proc delhaupttv {n u h c t} {
	if {[lsearch [channel info $c] -tvmovie]!=-1} {return}
	if {![tvcheckrights $n $h $c] || ![matchattr $h ${::tv-op} $c]} {putlog "TV-SCRIPT: $n ($h) hat nich genug Rechte in $c"; return}
	set flood [tvcheckflood $n $c]
	if {$flood} {set d $n} {set d $c}
	set sender [lindex [split $t] 0]
	if {[validchan $sender]} {
		set dc [string tolower $sender]
		set sender [lindex [split $t] 1]
		set sendung [join [lrange [split $t] 2 end]]
	} {
		set dc [string tolower $c]
		set sendung [join [lrange [split $t] 1 end]]
	}
	if {$sender==""} {
		puttv $d "Syntax: \002$::lastbind <sender>"; return
	}
	set sender [string map {" " *} $sender]
	set senderid [lindex [array names ::tv sender_$sender] 0]
	if {$senderid == ""} {
		puttv $d "Sender nicht gefunden."; return
	}
	set sendername [string range $senderid 7 end]
	set haupt [string trim [string tolower [channel get $c tv-haupt]]]
	if {$haupt==""} {set haupt ${::global-tv-haupt}; channel set $c tv-haupt $haupt}
	if {[set p [lsearch -exact [split $haupt] $sendername]]!=-1} {
		set haupt [split $haupt]
		set haupt [lreplace $haupt $p $p]
		set haupt [join $haupt]
		channel set $c tv-haupt $haupt
		puttv $d "Sender von den Hauptsendern entfernt."
	} {
		puttv $d "Sender ist nicht unter den Hauptsender."
	}
}
proc listhaupttv {n u h c t} {
	if {[lsearch [channel info $c] -tvmovie]!=-1} {return}
	if {![tvcheckrights $n $h $c] || ![matchattr $h ${::tv-op} $c]} {putlog "TV-SCRIPT: $n ($h) hat nich genug Rechte in $c"; return}
	set flood [tvcheckflood $n $c]
	if {$flood} {set d $n} {set d $c}
	set haupt [string trim [string tolower [channel get $c tv-haupt]]]
	if {$haupt==""} {set haupt ${::global-tv-haupt}; channel set $c tv-haupt $haupt}
	puttv $d "Die Hauptsender sind zur Zeit: $haupt"
}
bind pub - ${::tv-trigger}tvadd addremindtv
bind pub - ${::tv-trigger}tvdel delremindtv
bind pub - ${::tv-trigger}tvlist listremindtv
proc savetvlist {args} {
	set fh [open tv-remind.list w]
	puts $fh "set ::remindliste \[list $::remindliste\]"
	close $fh
}
proc loadtvlist {args} {
	if {[file exists tv-remind.list]} {source tv-remind.list}
}
proc addremindtv {n u h c t} {
	if {[lsearch [channel info $c] -tvmovie]!=-1} {return}
	if {![tvcheckrights $n $h $c] || ![matchattr $h ${::tv-op} $c]} {putlog "TV-SCRIPT: $n ($h) hat nich genug Rechte in $c"; return}
	set flood [tvcheckflood $n $c]
	if {$flood} {set d $n} {set d $c}
	set sender [lindex [split $t] 0]
	if {[validchan $sender]} {
		set dc [string tolower $sender]
		set sender [lindex [split $t] 1]
		set sendung [join [lrange [split $t] 2 end]]
	} {
		set dc [string tolower $c]
		set sendung [join [lrange [split $t] 1 end]]
	}
	set sendung [string map {" " *} $sendung]
	if {$sender=="" || $sendung==""} {
		puttv $d "Syntax: \002$::lastbind <sender> <sendung>\002"; return
	}
	set sender [string map {" " *} $sender]
	set senderid [lindex [array names ::tv sender_$sender] 0]
	if {$senderid == ""} {
		puttv $d "Sender nicht gefunden."; return
	}
	set sendername [string range $senderid 7 end]
	set f 0; set fitem [list]
	set c [string tolower $c];
	foreach item $::remindliste {
		if {$f} {break}
		foreach {ch s m} $item {
			if {$f} break
			if {[string match -nocase *$sendung* $m] || [string match -nocase *$m* $sendung]} {
				if {[string equal -nocase $sender $s]} {
					if {[lsearch -exact [split $ch ","] $dc]!=-1} {
						puttv $d "Es gibt bereits so eine Suchmaske."
						return
					} {
						set fitem $item
						set f 1
					}
				}
			}
		}
	}
	if {$f} {
		set pos [lsearch -exact $::remindliste $fitem]
		if {$pos!=-1} {
			set item [lindex $::remindliste $pos]
			set item [lreplace $item 0 0 [join [linsert [split [lindex $item 0] ,] 0 $dc] ,]]
			set ::remindliste [lreplace $::remindliste $pos $pos $item]
			puttv $d "Suchanfrage hinzugefügt, viel Glück! :)"
			savetvlist
		}
	} {
		lappend ::remindliste [list $dc $sender $sendung]
		puttv $d "Suchanfrage hinzugefügt, viel Glück! :)"
		savetvlist
	}
}
proc delremindtv {n u h c t} {
	if {[lsearch [channel info $c] -tvmovie]!=-1} {return}
	if {![tvcheckrights $n $h $c] || ![matchattr $h ${::tv-op} $c]} {putlog "TV-SCRIPT: $n ($h) hat nich genug Rechte in $c"; return}
	set flood [tvcheckflood $n $c]
	if {$flood} {set d $n} {set d $c}
	set sender [lindex [split $t] 0]
	if {[validchan $sender]} {
		set dc [string tolower $sender]
		set sender [lindex [split $t] 1]
		set sendung [join [lrange [split $t] 2 end]]
	} {
		set dc [string tolower $c]
		set sendung [join [lrange [split $t] 1 end]]
	}
	set sendung [string map {" " *} $sendung]
	if {$sender=="" || $sendung==""} {
		puttv $d "Syntax: \002$::lastbind <sender> <sendung>\002"
		return
	}
	set sender [string map {" " *} $sender]
	set senderid [lindex [array names ::tv sender_$sender] 0]
	if {$senderid == ""} {
		puttv $d "Sender nicht gefunden."; return
	}
	set sendername [string range $senderid 7 end]
	set f 0; set fitem [list]
	set c [string tolower $c]
	foreach item $::remindliste {
		if {$f} break
		foreach {ch s m} $item {
			if {$f} break
			if {[string match -nocase *$sendung* $m] || [string match -nocase *$m* $sendung]} {
				if {[string equal -nocase $sender $s]} {
					if {[lsearch -exact [split $ch ","] $dc]!=-1} {
						set fitem $item
						set f 1
					}
				}
			}
		}
	}
	if {$f} {
		set pos [lsearch -exact $::remindliste $fitem]
		if {$pos!=-1} {
			set item [lindex $::remindliste $pos]
			if {[llength [split [lindex $item 0] ,]]>1} {
				set p2 [lsearch [split [lindex $item 0] ,] $dc]
				set item [lreplace $item 0 0 [join [lreplace [split [lindex $item 0] ,] $p2 $p2] ,]]
				set ::remindliste [lreplace $::remindliste $pos $pos $item]
			} {
				set ::remindliste [lreplace $::remindliste $pos $pos]
			}
			puttv $d "Suchanfrage gelöscht."
			savetvlist

		}
	} {
		puttv $d "Keine passende Suchanfrage gefunden."
	}
}
proc listremindtv {n u h c t} {
	if {[lsearch [channel info $c] -tvmovie]!=-1} {return}
	if {![tvcheckrights $n $h $c] || ![matchattr $h ${::tv-op} $c]} {putlog "TV-SCRIPT: $n ($h) hat nich genug Rechte in $c"; return}
	set flood [tvcheckflood $n $c]
	if {$flood} {set d $n} {set d $c}
	set c [string tolower $c]
	set t [string trim [string tolower $t]]
	if {[validchan $t]} {set dc [string tolower $t]} {set dc [string tolower $c]}
	set found 0
	foreach item [lsort -index 2 [lsort -index 1 $::remindliste]] {
		foreach {ch s m} $item {
			if {[lsearch [split $ch ,] $dc]!=-1} {
				incr found
				puttv $d "${found}. ($s) \002$m\002"
			}
		}
	}
	if {$found==0} {
		puttv $d "Keine Suchanfragen gefunden."
	} { puttv $d "Ende."}
}

proc remindtv {dest sender sendung} {
	set sender [string map {" " *} $sender]
	set senderid [lindex [array names ::tv sender_$sender] 0]
	if {$senderid == ""} {
		return
		puttv $dest "Sender nicht gefunden."; return
	}
	set sendername [string range $senderid 7 end]
	if {![info exists ::tvcache($sendername)]} {return}
	set h [clock format [clock scan -1hour] -format %k]
	set m [clock format [clock scan -1hour] -format %M]
	set howmuch 5
	if {[string index $m 0]=="0"} {set m [string range $m 1 end]}
	set searchs 0; set sttime [unixtime]
	for {set i 0} {$i < [llength $::tvcache($sendername)]} {incr i 3} {
		if  {[unixtime]-$sttime>10} break
		set time [lindex $::tvcache($sendername) $i]
		if {[string index $time 0] == "0"} { set hour [string index $time 1] } else { set hour [string range $time 0 1] }
		set min [string range $time 3 4]
		if {$hour > $h} {
			set nums 0; set searchs 0
			incr i -3
			while {$nums < $howmuch && [unixtime]-$sttime<=10} {
				incr searchs
				if {$searchs>500} break
				set time [lindex $::tvcache($sendername) $i]; incr i
				if {[string index $time 0] == "0"} { set hour [string index $time 1] } else { set hour [string range $time 0 1] }
				set min [string range $time 3 4]
				#if {$hour > 23} { incr hour -24 }
				set time $hour:$min
				set what [decrypt specialchar [lindex $::tvcache($sendername) $i]]; incr i
				set descr [decrypt specialchar [lindex $::tvcache($sendername) $i]]; incr i
				if {[regexp {^\s*?(\(.*\))(.*)$} $descr "" temp descr]} { set what "$what $temp"; set descr [string trim $descr] }
				if {$time != "" && $time!= ":"} {
					if {[string match -nocase *$sendung* $what]} {
						set clkt2 [clock form [clock sec] -form "%H:%M"]; 
						if {![info exis clkt3]} {set clkt3 ""}
						if {$clkt2!=$clkt3} {
							#putcmdlog "tv_beta.tcl: clkt2:'$clkt2'; what:'$what'; time:'$time'; h:$hour; m:$min;";
							set clkt3 $clkt2
						}
						if {$descr!=""} {
							if {$clkt2==""} {
							set cmd [list puttv $dest "\002JETZT\002 ($sendername) \002$what\002 \[$descr\]"]
							set cmd2 [list puttv $dest "\002In 5 Minuten\002 ($sendername) \002$what\002 \[$descr\]"]
							} elseif {$clkt2=="23:50"} {
							if {$hour > 23} {set th [expr {$hour - 24}]} {set th $hour}
							set cmd [list puttv $dest "\002HEUTE\002 ($sendername) ${th}:${min} \002$what\002 \[$descr\]"]
							set cmd2 [list puttv $dest "\002MORGEN\002 ($sendername) \002$what\002 \[$descr\]"]
							} {
							set cmd [list puttv $dest "\002JETZT\002 ($sendername) \002$what\002 \[$descr\]"]
							set cmd2 [list puttv $dest "\002In 5 Minuten\002 ($sendername) \002$what\002 \[$descr\]"]
							}
						} {
							if {$clkt2=="23:50"} {
								if {$hour > 23} {set th [expr {$hour - 24}]} {set th $hour}
								set cmd [list puttv $dest "\002HEUTE\002 ($sendername) ${th}:${min} \002$what\002"]
								set cmd2 [list puttv $dest "\002MORGEN\002 ($sendername) \002$what\002"]
							} {
								set cmd [list puttv $dest "\002JETZT\002 ($sendername) \002$what\002"]
								set cmd2 [list puttv $dest "\002In 5 Minuten\002 ($sendername) \002$what\002"]
							}
						}
						set diff [expr {[clock scan $time]-[clock seconds]}]
						if {$diff+86400<666} {set diff [expr {$diff+86400}]}
						if {$diff>330 && $diff<666} {
							#if {[info command stimer]=="stimer"} {stimer 10 cachetvdata} {utimer 10 cachetvdata}
							if {[info command stimer]=="stimer"} {
								if {[stimerexists $cmd]==""} {
									set tid2 [stimer [expr {$diff-312}] $cmd2]
									set tid [stimer [expr {$diff-12}] $cmd]
								}
							} {
								if {[utimerexists $cmd]==""} {
									set tid2 [utimer [expr {$diff-312}] $cmd2]
									set tid [utimer [expr {$diff-12}] $cmd]
								}
							}
						}
						incr nums
					}
				}
			}
			break
		}
	}
}



proc cachetvdata {{args ""}} {
	if {![info exists ::tv(cacheindex)]} {
		putlog "Starting to cache TV data..."
		unset -nocomplain ::tv ::tvcache
                putlog "Getting TV Stations"
                if {[catch {set t [http::geturl "http://www.tvmovie.de/tv-programm/tv-station-chooser.html" -timeout 25000]} err]} {
                  putlog "Error while fetching TV Stations" ;return
                } elseif {[http::status $t]!="ok"} {
                  putlog "Error while fetching TV Stations: [http::status $t]"; http::cleanup $t ;return
                }
                set h [encoding convertfrom utf-8 [http::data $t]]
                set doc [dom parse -html $h]
                set root [$doc documentElement]
                if {$root==""} {putlog "Error while fetching TV Stations"; $doc delete; return}
                foreach n [$root selectNodes {//a[@class="tv-station link-for-parent"]}] {
                  set curl "[string trim [$n selectNode {string(./@href)}]]"
                  set cgroup "[string range $curl [expr [string first = $curl]+1] end]"
                  set cname "[string map [list " " ""] [string tolower [string trim [$n selectNode {string(./span)}]]]]"
                  regsub -all {[^a-zA-Z0-9]} $cname "\\1" cname
                  set cname [string map [list "rtlii" "rtl2"] $cname]
                  if {[string tolower [string range $cname end-1 end]]=="hd"} { 	set cname [string range $cname 0 end-2]              }
                  if {![info exists ::tv(groups)] || [lsearch -exact $::tv(groups) $cgroup]=="-1"} {lappend ::tv(groups) $cgroup}
                  if {![info exists ::tv(sender_$cname)]} {set ::tv(sender_$cname) $cgroup}
                }
                $doc delete
                putlog "Found [llength [array names ::tv sender_*]] Stations"
                set ::tv(cacheindex) 0
	}
	if {![info exists ::tv(groups)]} {
		set gid 0
	} elseif {$::tv(cacheindex)>=[llength $::tv(groups)]} {
		savecache
		putlog "Okay, cached all data"
		unset ::tv(cacheindex)
		return
	} {set gid [lindex $::tv(groups) $::tv(cacheindex)]}
	if {![info exists ::tv(groups)]} {putloglev 1 * "Getting info for stations group $gid"} {putloglev 1 * "Getting info for stations group $gid ([expr $::tv(cacheindex)+1] / [llength $::tv(groups)])"}
	tv_getinfo $gid
	#putloglev 1 * "Got info (found [expr {[llength $::tvcache($sendername)] / 2}] entries)"
	incr ::tv(cacheindex)
	if {[info command stimer]=="stimer"} {stimer 45 cachetvdata} {utimer 45 cachetvdata}
	#utimer 15 cachetvdata
}
proc tv_getinfo {gid {noretry 0}} {
	http::config -useragent {Mozilla/5.0 (Windows NT 6.0; rv:6.0.1) Gecko/20100101 Firefox/6.0.1}
	set url "http://www.tvmovie.de/tv-programm-heute.html?date=[clock format [clock seconds] -format "%Y-%m-%d"]&tv-stations-group=${gid}&nocache=true"
	if {[catch {set t [http::geturl $url -timeout 25000]} err]} {
		if {[info command stimer]=="stimer"} {
			if {$noretry<99 && [stimerexists [list tv_getinfo $gid $noretry]]==""} {incr noretry; stimer [expr {int(rand()*1200)+300}] [list tv_getinfo $gid $noretry]}
		} {
			if {$noretry<99 && [utimerexists [list tv_getinfo $gid $noretry]]==""} {incr noretry; utimer [expr {int(rand()*1200)+300}] [list tv_getinfo $gid $noretry]}
		}
		putloglev 1 * "Error while fetching Data for stations-group $gid" ;return
	} elseif {[http::status $t]!="ok"} {
		if {[info command stimer]=="stimer"} {
			if {$noretry<99 && [stimerexists [list tv_getinfo $gid $noretry]]==""} {incr noretry; stimer [expr {int(rand()*1200)+300}] [list tv_getinfo $gid $noretry]}
		} {
			if {$noretry<99 && [utimerexists [list tv_getinfo $gid $noretry]]==""} {incr noretry; utimer [expr {int(rand()*1200)+300}] [list tv_getinfo $gid $noretry]}
		}
		putloglev 1 * "HTTP-Error ($url): [http::status $t]"
		http::cleanup $t
		return
	}
	set h [encoding convertfrom utf-8 [http::data $t]]
	upvar #0 $t state
	set f [open tvmovie.html w] ;puts $f "$url - [http::status $t] -> [string range [http::data $t] 0 50]....[array get state]"; puts $f $h; close $f
	http::cleanup $t
	set doc [dom parse -html $h]
	set root [$doc documentElement]
	if {$root==""} {
		if {!$noretry && [timerexists [list tv_getinfo $gid 1]]==""} {timer 5 [list tv_getinfo $gid 1]}
		$doc delete
		putloglev 1 * "Error while fetching Data for stations-group $gid"; return
	}
	#foreach n [$root selectNodes {//div[@class="tv-station-selection"]/div/div/a[@class="tv-stations-group"]}] {
        # 		
        #                 set group "[string range [string trim [$n selectNode {string(./@href)}]] [expr [string first = [string trim [$n selectNode {string(./@href)}]]]+1] end]"
        # 		if {![info exists ::tv(groups)] || [lsearch -exact $::tv(groups) $group]=="-1"} {lappend ::tv(groups) $group}
        #	}
	#foreach n [$root selectNodes {//div[@class="day-selection"]/a}] {set surl "[file dirname $url][string trim [$n selectNode {string(./@href)}]]"; set sday [string trim [$n selectNode {string(.)}]]}
	if {![info exists ::tv(senderliste)]} {set ::tv(senderliste) [list]}
	#foreach n [$root selectNodes {//div[@id="tv-stations-selection"]/div/a}] {
        #		set cg [string trim [$n selectNode {string(./@href)}]]
        #        if {[string first = $cg]!="-1"} {set cgroup [string range $cg [expr [string first = $cg]+1] end]} {set cgroup 0}
        #        foreach n1 [$n selectNodes {./span}] {
        #			set cname [string map [list " " ""] [string tolower [string trim [$n1 selectNode {string(./img/@alt)}]]]]
        #                regsub -all {[^a-zA-Z0-9]} $cname "\\1" cname
	#		if {[lsearch -exact $::tv(senderliste) $cname]=="-1"} {lappend ::tv(senderliste) $cname $cgroup; set ::tv(sender_$cname) $cgroup}
	#	}
	#}
	set sid 0; set cid 0; set eid -1
	foreach n [$root selectNodes {//table[@class="tv-guide-table"]/tr}] {
		foreach n1 [$n selectNodes {./td[@class="tv-station-info tv-station-logo"]}] {
			set nam "[string map [list " " ""] [string tolower [string trim [$n1 selectNode {string(.)}]]]]"
                        regsub -all {[^a-zA-Z0-9]} $nam "\\1" nam
                        set nam [string map [list "rtlii" "rtl2"] $nam]
                        if {[string tolower [string range $nam end-1 end]]=="hd"} { set nam [string range $nam 0 end-2] }
			set tmp($cid) $nam
			incr cid; incr eid
		}
		foreach n2 [$n selectNodes {./td[@class="broadcasts-cell" or @class="broadcasts-cell has-regional-switcher"]}] {
			foreach n3 [$n2 selectNodes {./div/div}] {
				if {![info exists tmp($sid)]} {incr sid -1}
				set t [string trim [$n3 selectNode {string(./div[@class="left"]/div[@class="time"])}]]
				if {[string match -nocase "ca. *" $t]} {set t [string range $t 4 end]}
				set hr [lindex [lindex [split $t :] 0] end]
				set min [lindex [split $t :] 1]
				if {$t==""} {continue}
				if {![string is digit -strict $hr] || ![string is digit -strict $min]} {putloglev 2 * "Skipped entry for $tmp($sid) - Invalid Timestamp ($t)"; continue}
				set s [string trim [$n3 selectNode {string(./div[@class="right"]/a[@class="title"])}]]
				set c [string trim [$n3 selectNode {string(./div/div[@class="genre"])}]]
				putloglev 2 * "Got a new entry for $tmp($sid): \"$t($hr:$min)\" \"$s\" \"$c\""
				if {[string index $hr 0] == 0 && [string index $hr 1] < 5} { incr hr 24 }
				set t $hr:$min
				lappend ::tvcache([subst $tmp($sid)]) "$t" "[encrypt specialchar $s]" "[encrypt specialchar $c]"
			}
			if {$sid==$eid} {set sid [expr $sid-$eid]} {incr sid}
		}
	}
	$doc delete
	savecache
}





set ::remindliste [list]
loadcache
loadtvlist
if {![info exists ::tvcache(ard)]} {
	if {[info command stimer]=="stimer"} {
		if {[stimerexists cachetvdata]==""} {stimer 60 cachetvdata}
	} {
		if {[utimerexists cachetvdata]==""} {utimer 60 cachetvdata}
	}
}
set tv-version "-nix-"
if {![gets [set f [open [info script]]] tv-version]} {set tv-version "-Fehler-"} {set tv-version [lindex [string trim ${tv-version}] end]}; close $f
putlog "TV Script ${tv-version} loaded ([info script])"
if {[info level]=="0" || ![string match "tcldebug:*" [info level [expr {[info level]-1}]]]} {return "load \"[info script] ${tv-version}\",8,1\nready\nrun"}

 

Link to comment
Share on other sites



×
×
  • Create New...