All pastes #227211 Raw Edit

Mine

public text v1 · immutable
#227211 ·published 2006-10-29 03:08 UTC
rendered paste body
################################################################################
#                                                                              #
#             TVRage - TV Show & Episode Pzs-ng Plug-in v1.3b                  #
#                       by Meij <meijie@gmail.com>                             #
#                                                                              #
################################################################################
#
# Description:
# - Announce information obtained from tvrage.com on pre and new releases.
#
# Installation:
# 1. Copy this file (TVRage.tcl) into your pzs-ng sitebots 'plugins' folder.
#
# 2. Edit the configuration options below.
#
# 3. Add the following to your eggdrop.conf:
#    source pzs-ng/plugins/TVRage.tcl
#
# 4. Add the following to dZSbot.conf:
#    set disable(TVRAGE)           0
#    set disable(TVRAGE-PRE)       0
#    set disable(TVRAGE-MSGFULL)   0
#    set disable(TVRAGE-MSGSHOW)   0
#    set variables(TVRAGE)         "$variables(NEWDIR) %tvrage_show_name %tvrage_show_genres %tvrage_show_country %tvrage_show_status %tvrage_show_latest_title %tvrage_show_latest_episode %tvrage_show_latest_airdate %tvrage_show_next_title %tvrage_show_next_episode %tvrage_show_next_airdate %tvrage_show_url %tvrage_show_classification %tvrage_show_premiered %tvrage_episode_url %tvrage_episode_season_episode %tvrage_episode_season %tvrage_episode_number %tvrage_episode_original_airdate %tvrage_episode_title %tvrage_episode_production_number %tvrage_episode_score"
#    set variables(TVRAGE-PRE)     "$variables(PRE) %tvrage_show_name %tvrage_show_genres %tvrage_show_country %tvrage_show_status %tvrage_show_latest_title %tvrage_show_latest_episode %tvrage_show_latest_airdate %tvrage_show_next_title %tvrage_show_next_episode %tvrage_show_next_airdate %tvrage_show_url %tvrage_show_classification %tvrage_show_premiered %tvrage_episode_url %tvrage_episode_season_episode %tvrage_episode_season %tvrage_episode_number %tvrage_episode_original_airdate %tvrage_episode_title %tvrage_episode_production_number %tvrage_episode_score"
#    set variables(TVRAGE-MSGFULL) "%tvrage_show_name %tvrage_show_genres %tvrage_show_country %tvrage_show_status %tvrage_show_latest_title %tvrage_show_latest_episode %tvrage_show_latest_airdate %tvrage_show_next_title %tvrage_show_next_episode %tvrage_show_next_airdate %tvrage_show_url %tvrage_show_classification %tvrage_show_premiered %tvrage_episode_url %tvrage_episode_season_episode %tvrage_episode_season %tvrage_episode_number %tvrage_episode_original_airdate %tvrage_episode_title %tvrage_episode_production_number %tvrage_episode_score"
#    set variables(TVRAGE-MSGSHOW) $variables(TVRAGE-MSGFULL)
#
#    set zeroconvert(%tvrage_show_name)                 "N/A"
#    set zeroconvert(%tvrage_show_genres)               "N/A"
#    set zeroconvert(%tvrage_show_country)              "N/A"
#    set zeroconvert(%tvrage_show_status)               "N/A"
#    set zeroconvert(%tvrage_show_latest_title)         "N/A"
#    set zeroconvert(%tvrage_show_latest_episode)       "N/A"
#    set zeroconvert(%tvrage_show_latest_airdate)       "N/A"
#    set zeroconvert(%tvrage_show_next_title)           "N/A"
#    set zeroconvert(%tvrage_show_next_episode)         "N/A"
#    set zeroconvert(%tvrage_show_next_airdate)         "N/A"
#    set zeroconvert(%tvrage_show_url)                  "N/A"
#    set zeroconvert(%tvrage_show_classification)       "N/A"
#    set zeroconvert(%tvrage_show_premiered)            "N/A"
#    set zeroconvert(%tvrage_episode_url)               "N/A"
#    set zeroconvert(%tvrage_episode_season_episode)    "N/A"
#    set zeroconvert(%tvrage_episode_season)            "N/A"
#    set zeroconvert(%tvrage_episode_number)            "N/A"
#    set zeroconvert(%tvrage_episode_original_airdate)  "N/A"
#    set zeroconvert(%tvrage_episode_title)             "N/A"
#    set zeroconvert(%tvrage_episode_production_number) "N/A"
#    set zeroconvert(%tvrage_episode_score)             "-"
#
# 5. Add the following to your theme file (.zst).
#    announce.TVRAGE           = "[%b{TV-INFO}][%section] %b{%tvrage_show_name}: %b{%tvrage_episode_title} (%tvrage_show_genres) Aired: %tvrage_episode_original_airdate\n[%b{TV-INFO}][%section] URL: %tvrage_episode_url"
#
#    announce.TVRAGE-PRE       = "[%b{TV-INFO}][%section] %b{%tvrage_show_name}: %b{%tvrage_episode_title} (%tvrage_show_genres) Aired: %tvrage_episode_original_airdate\n[%b{TV-INFO}][%section] URL: %tvrage_episode_url"
#
#    announce.TVRAGE-MSGFULL   = "[%b{TV-INFO}] %b{%tvrage_show_name}: %b{%tvrage_episode_title} (%tvrage_show_genres) Aired: %tvrage_episode_original_airdate\n[%b{TV-INFO}] URL: %tvrage_episode_url"
#    announce.TVRAGE-MSGSHOW   = "[%b{TV-INFO}] %b{%tvrage_show_name} (%tvrage_show_genres)\n[%b{TV-INFO}] Last Episode: %b{%tvrage_show_latest_episode: %tvrage_show_latest_title} (%tvrage_show_latest_airdate)\n[%b{TV-INFO}] Next Episode: %b{%tvrage_show_next_episode: %tvrage_show_next_title} (%tvrage_show_next_airdate)\n[%b{TV-INFO}] URL: %tvrage_show_url"
#
# 6. Rehash or restart your eggdrop for the changes to take effect.
#
#################################################################################

namespace eval ::ngBot::TVRage {
	variable events
	variable tvrage

	## Config Settings ###############################
	##
	set tvrage(sections) { "/site/incoming/tv" }
	##
	## Timeout in milliseconds. (default: 3000)
	set tvrage(timeout)  3000
	##
	## Announce when no data was found. (default: false)
	set tvrage(announce-empty) false
	##
	## Channel trigger. (Leave blank to disable)
	set tvrage(ctrigger) "!tv"
	##
	## Private message trigger. (Leave blank to disable)
	set tvrage(ptrigger) ""
	##
	## Date format. (URL: http://tcl.tk/man/tcl8.4/TclCmd/clock.htm)
	set tvrage(date)     "%Y-%m-%d"
	##
	## Skip announce for these directories.
	set tvrage(ignore_dirs) {cd[0-9] dis[ck][0-9] dvd[0-9] codec cover covers extra extras sample subs vobsub vobsubs}
	##
	## Genre splitter.
	set tvrage(splitter) " / "
	##
	## Pre line regexp.
	##  We need to reconstruct the full path to the release. Since not all
	##  pre scripts use the same format we'll use regexp to extract what we
	##  need from the pre logline and reconstuct it ourselves.
	##
	##  Default f00-pre example:
	set tvrage(pre-regexp) {^"(.[^"]+)" ".[^"]*" ".[^"]*" "(.[^"]+)"}
	set tvrage(pre-path)   "%2/%1"
	##
	##  Default eur0-pre example:
	#set tvrage(pre-regexp) {^"(.[^"]+)"}
	#set tvrage(pre-path)   "%1"
	##
	##################################################

	set events [list "NEWDIR" "PRE"]

	variable scriptName [namespace current]::LogEvent
	bind evnt -|- prerehash [namespace current]::DeInit
}

proc ::ngBot::TVRage::Init {args} {
	global postcommand

	variable events
	variable tvrage
	variable scriptName

	if {[catch {package require http}] != 0} {
		[namespace current]::Error "\"http\" package not found, unloading script."
		[namespace current]::DeInit
		return
	}

	## Register the event handler.
	foreach event $events {
		lappend postcommand($event) $scriptName
	}

	if {([info exists tvrage(ctrigger)]) && (![string equal $tvrage(ctrigger) ""])} {
		bind pub -|- $tvrage(ctrigger) [namespace current]::Trigger
	}
	if {([info exists tvrage(ptrigger)]) && (![string equal $tvrage(ptrigger) ""])} {
		bind msg -|- $tvrage(ptrigger) [namespace current]::Trigger
	}

	putlog "\[ngBot\] TVRage :: Loaded successfully."
}

proc ::ngBot::TVRage::DeInit {args} {
	global postcommand

	variable events
	variable tvrage
	variable scriptName

	## Remove the script event from postcommand.
	foreach event $events {
		if {[info exists postcommand($event)] && [set pos [lsearch -exact $postcommand($event) $scriptName]] !=  -1} {
			set postcommand($event) [lreplace $postcommand($event) $pos $pos]
		}
	}

	catch {unbind pub -|- $tvrage(ctrigger) [namespace current]::Trigger}
	catch {unbind msg -|- $tvrage(ptrigger) [namespace current]::Trigger}
	catch {unbind evnt -|- prerehash [namespace current]::DeInit}

	namespace delete [namespace current]
}

proc ::ngBot::TVRage::Error {error} {
	putlog "\[ngBot\] TVRage :: Error: $error"
}

proc ::ngBot::TVRage::ConvertDate {string} {
	variable tvrage

	set tmp [string map { "/" " " } $string]
	if {[set i [string last " " $tmp]] != -1} {
		set tmp [string replace $tmp $i $i ", "]
	}

	if {[catch {clock format [clock scan $tmp] -format $tvrage(date)} result] == 0} {
		set string $result
	}

	return $string
}

proc ::ngBot::TVRage::Trigger {args} {
	variable tvrage

	if {[llength $args] == 5} {
		checkchan [lindex $args 2] [lindex $args 3]

		set trigger $tvrage(ctrigger)
	} else {
		set trigger $tvrage(ptrigger)
	}

	set text [lindex $args [expr { [llength $args] - 1 }]]
	set target [lindex $args [expr { [llength $args] - 2 }]]

	if {[string equal $text ""]} {
		sndone $target "TVRage Syntax :: $trigger <string> (eg: $trigger Stargate SG-1 S02E10)"
		return 1
	}

	if {[catch {[namespace current]::FindInfo $text [list] "false"} logData] != 0} {
		sndone $target "TVRage Error :: $logData"
		return 0
	}

	## Display full series/episode info if episode_url exists
	if {![string equal [lindex $logData 13] ""]} {
		sndone $target [ng_format "TVRAGE-MSGFULL" "none" $logData]
	} else {
		sndone $target [ng_format "TVRAGE-MSGSHOW" "none" $logData]
	}

	return 1
}

proc ::ngBot::TVRage::LogEvent {event section logData} {
	variable tvrage

	if {[string compare -nocase $event "NEWDIR"] == 0} {
		set target "TVRAGE"

		set release [lindex $logData 0]
	} else {
		set target "TVRAGE-PRE"

		if {(![info exists tvrage(pre-regexp)]) || (![info exists tvrage(pre-path)])} {
			[namespace current]::Error "Your pre-regexp or pre-path variables are not set"
			return 0
		}

		if {[catch {regexp -inline -nocase -- $tvrage(pre-regexp) $logData} error] != 0} {
			[namespace current]::Error $error
			return 0
		}

		if {[set cookies [regexp -inline -all -- {%([0-9]+)} $tvrage(pre-path)]] == ""} {
			[namespace current]::Error "Your pre-path contains no valid cookies"
			return 0
		}

		set release $tvrage(pre-path)
		foreach {cookie number} $cookies {
			regsub -- $cookie $release [lindex $error $number] release
		}
	}

	## Check the release directory is ignored.
	foreach ignore [split $tvrage(ignore_dirs) " "] {
		if {[string match -nocase $ignore [file tail $release]]} {
			return 1
		}
	}

	foreach path $tvrage(sections) {
		if {[string match -nocase "$path*" $release]} {
			set logLen [llength $logData]

			if {[catch {[namespace current]::FindInfo [file tail $release] $logData} logData] != 0} {
				[namespace current]::Error "$logData. ($release)"
				return 0
			}

			set empty 1
			foreach piece [lrange $logData $logLen end] {
				if {![string equal $piece ""]} {
					set empty 0

					break
				}
			}

			if {($empty == 0) || ([string is true -strict $tvrage(announce-empty)])} {
				sndall $target $section [ng_format $target $section $logData]
			}

			break
		}


	}

	return 1
}

proc ::ngBot::TVRage::FindInfo {string logData {strict true}} {
	set output_order [list show_name show_genre show_country show_status \
	                       show_latest_title show_latest_episode \
	                       show_latest_airdate show_next_title \
	                       show_next_episode show_next_airdate show_url \
	                       show_classification show_premiered episode_url \
	                       episode_season_episode episode_season \
	                       episode_number episode_original_airdate \
	                       episode_title episode_production_number \
	                       episode_score]

	set show_str $string
	if {(![regexp -- {^(.*?)(\d+x\d+|[sS]\d+[eE]\d+).*$} $string -> show_str episode_str]) && \
	    ([string is true -strict $strict])} {
		error "Unable to parse season and episode info from \"$string\""
	}

	catch {regexp -- {^(\d+)x(\d+)$} $episode_str -> episode_season episode_number}
	catch {regexp -- {^[sS](\d+)[eE](\d+)$} $episode_str -> episode_season episode_number}

	regsub -all -- {[\._]} $show_str " " show_str
	set show_str [string trim $show_str]

	::http::config -useragent "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7"

	array set info [[namespace current]::GetShow $show_str]
	if {([info exists episode_season]) && ([info exists episode_number]) && \
	    ([info exists info(show_url)])} {
		array set info [[namespace current]::FindEpisode $info(show_url) $episode_season $episode_number]

		if {[info exists info(episode_url)]} {
			array set info [[namespace current]::GetEpisode $info(episode_url)]
		}
	}

	foreach key $output_order {
		if {(![info exists info($key)]) || \
		    ([string equal -nocase $info($key) "&nbsp;"])} {
			set info($key) ""
		}

		lappend logData $info($key)
	}

	return $logData
}

proc ::ngBot::TVRage::GetShow {show} {
	variable tvrage

	set token [::http::geturl "http://www.tvrage.com/quickinfo.php?show=[::http::formatQuery $show]" -timeout $tvrage(timeout)]

	if {![string equal -nocase [::http::status $token] "ok"]} {
		return -code error "Connection [::http::status $token]"
	}

	## Its pointless checking the http status, its always 200. Errors are
	## redirected on the server to an 'Unknown Page' error page.

	set data [::http::data $token]
	set matches [regexp -inline -nocase -all -- {(.[^@]+)@(.[^\n\r]+)(?:[\n\r]*)} $data]

	if {[string length $matches] == 0} {
		return -code error "No results found for \"$show\""
	}

	foreach {junk key value} $matches {
		set key [string map { " " "_" } [string tolower $key]]

		switch -glob $key {
			latest_episode -
			next_episode {
				regsub -- {_\w+} $key "" key

				regexp -- {(.[^\^]+)\^(.[^\^]+)\^(.*)} $value -> info(show_$key\_episode) info(show_$key\_title) info(show_$key\_airdate)

				set info(show_$key\_airdate) [[namespace current]::ConvertDate $info(show_$key\_airdate)]
			}
			genres {
				set info(show_genre) [list]

				foreach genre [split $value "|"] {
					lappend info(show_genre) [string trim $genre]
				}

				set info(show_genre) [join $info(show_genre) $tvrage(splitter)]
			}
			show_* {
				set info($key) $value
			}
			default {
				set info(show_$key) $value
			}
		}
	}

	if {![info exists info(show_url)]} {
		return -code error "Invalid results found for \"$show\""
	}

	return [array get info]
}

proc ::ngBot::TVRage::FindEpisode {url season episode} {
	variable tvrage

	set token [::http::geturl "$url/episode_list/$season" -timeout $tvrage(timeout)]

	## Its pointless checking the http status, its always 200. Errors are
	## redirected on the server to an 'Unknown Page' error page.

	set data [::http::data $token]

	regexp -- {<font size=.?4.?>Season (\d+)</font>} $data -> tmp_season

	if {[string trimleft $season "0"] != $tmp_season} {
		error "Invalid season information. Website returned season $tmp_season, we were expecting $season"
	}

	set matches [regexp -inline -nocase -all -- {<tr bgcolor='#.*?'>.+?</tr>} $data]

	if {[string length $matches] == 0} {
		error "No results found for \"$season\x$episode\""
	}

	foreach junk $matches {
		regexp -nocase -- {<td width='40'.[^>]+><a href='(.[^']+)'>\d+x(\d+)</i></a></td>} $junk -> tmp_url tmp_episode

		if {$episode == $tmp_episode} {
			set info(episode_url) "http://www.tvrage.com$tmp_url"

			break
		}

		catch {unset tmp_url tmp_episode}
	}

	if {![info exists info(episode_url)]} {
		error "Invalid results found for \"$season\x$episode\""
	}

	return [array get info]
}

proc ::ngBot::TVRage::GetEpisode {url} {
	variable tvrage

	set token [::http::geturl $url -timeout $tvrage(timeout)]

	## Its pointless checking the http status, its always 200. Errors are
	## redirected on the server to an 'Unknown Page' error page.

	set data [::http::data $token]

	if {[set edata [regexp -inline -nocase -- {<table class='b' width='100%' cellspacing='0'>.+?</table>} $data]] != ""} {
		set matches [regexp -inline -nocase -all -- {<b>(.+?): </b></td><td.*?>(.+?)</td>} $edata]

		foreach {junk key value} $matches {
			set key [string trim [string map { "#" "" } $key]]
			set key [string map { " " "_" } [string tolower $key]]
			set key [string trimright $key "._"]

			switch -glob $key {
				original_airdate {
					set info(episode_$key) [[namespace current]::ConvertDate $info(episode_$key)]
				}
				writer -
				director {
					set tmp [regexp -inline -nocase -all -- {<a  href='(.+?)' >(.+?)</a><br>} $value]

					foreach {tmp_junk tmp_url tmp_name} $tmp {
						lappend info(episode_$key) $tmp_name $tmp_url
					}

					catch {unset tmp tmp_junk tmp_url tmp_name}
				}
				episode_* {
					set info($key) $value
				}
				score {
					## TODO
					set info(episode_score) ""
				}
				default {
					set info(episode_$key) $value
				}
			}
		}
	}

	if {![info exists info]} {
		error "Unable to parse episode information"
	}

	return [array get info]
}

::ngBot::TVRage::Init