This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

TVRage.com Schedule Script (Latest: 2.0)

Support & discussion of released scripts, and announcements of new releases.
Post Reply
f
fanatic
Voice
Posts: 7
Joined: Mon Aug 21, 2006 5:25 pm

%%summary%%

Post by fanatic »

Hi,


is missing part of %%summary%%

:D
G
GaveUp
Op
Posts: 139
Joined: Thu Jan 19, 2006 3:56 am

Post by GaveUp »

That message makes absolutely no sense to me.
f
fanatic
Voice
Posts: 7
Joined: Mon Aug 21, 2006 5:25 pm

Post by fanatic »

Hi,

Ive edited the colours and the messages, but the !sumarry command isnt working

[17:09:17] <!fanatic> !summary lost 02x23
[17:09:19] <+Mary> ( Série: Lost ) - ( Episodio: 02x23 Live Together (1) (24/May/2006 ) - ( Summary: {%%summary%%} )
G
GaveUp
Op
Posts: 139
Joined: Thu Jan 19, 2006 3:56 am

Post by GaveUp »

For a temporary fix find the line

Code: Select all

if {[regexp "<table width=\'98%\' align='center'><tr><td>(.*)</td></tr></table>" $line -> match]} { set show(summary) $match }
and change it to

Code: Select all

regsub -all "\n" $data "" data
regsub -all "<br>" $data "" data
if {[regexp "<table width=\'98%\' align='center'><tr><td>(.*?)</td></tr></table>" $line -> match]} { set show(summary) $match }
In a few days I will post an updated version with this patch, and some other features I've been working on.
f
fanatic
Voice
Posts: 7
Joined: Mon Aug 21, 2006 5:25 pm

Post by fanatic »

ive modified the file, but still doesnt work
G
GaveUp
Op
Posts: 139
Joined: Thu Jan 19, 2006 3:56 am

Post by GaveUp »

Without something more substantial that "it doesn't work" I can offer no suggestions. It works here, if it didn't I'd have not made the previous post.
F
Fredgremlin
Voice
Posts: 1
Joined: Sat Sep 16, 2006 4:20 am

Post by Fredgremlin »

Hey there... GREAT script - just installed it, and it mostly worked out of the box.


The summary thing didn't work for me either - but only on certain TV episodes. E.g. Lost 02x24

The problem is that some of the "comments " are split across multiple lines.. so the regexp does not work. The fix above is a "partial fix".

I removed the foreach loop, so that the regularexpressions effectively turn the HTML into one big long line, and match on that. It may not be the most efficient way of doing things, but it's a quick fix.

Code: Select all

#   foreach line [split $data \n] {
      regsub -all "\n" $data "" data
      regsub -all "<br>" $data " " data
      if {[regexp "<table width=\'98%\' align='center'><tr><td>(.*?)</td></tr></table>" $data -> match]} {
        set show(summary) $match
      }
   #}
So other problems having installed...

1) My users hammered the hell out of the script spamming the main channel. I changed the {%%chan%%} to {%%nick%%} in the messages so that responses appeared in a PM. I took it one step further to implement a way they could talk to the bot in PM.

Code: Select all

bind msg - $tvrage(summaryTrigger) pub:tvrage.com.getSummary.m

proc pub:tvrage.com.getSummary.m {nick host handle text} { return [pub:tvrage.com.getSummary $nick $host $handle $nick $text] }

etc...
And change all (3)

Code: Select all

   if ![channel get $chan tv]  return
To

Code: Select all

   if {$nick!=$chan} { if ![channel get $chan tv]  return}

2) I disabled the schedule listings from my users initially
It would be useful to add this to the configuration..

Code: Select all


set tvrage(enableSummary)  1
set tvrage(enableShowInfo) 1
set tvrage(enableSchedule) 1

...

if {$tvrage(enableSchedule)} {
        bind pub - $tvrage(todayTrigger) pub:tvrage.com.today
        bind pub - $tvrage(tomorrowTrigger) pub:tvrage.com.tomorrow
        bind pub - $tvrage(scheduleTrigger) pub:tvrage.com.schedule
}
if {$tvrage(enableShowInfo)} {
        bind pub - $tvrage(showinfoTrigger) pub:tvrage.com.showinfo
}
if {$tvrage(enableSummary)} {
        bind pub - $tvrage(summaryTrigger) pub:tvrage.com.getSummary
}

3) Some of the error messages appear in the log, rather than get back to the user.

Code: Select all

# Format of info to show when !showinfo does not find a parameter
set tvrage(showInfoUsage) "PRIVMSG {%%nick%%} :\00303Usage: !showinfo <show name>\00315"

# Format of Invalid Request
set tvrage(invalidRequestLine) "PRIVMSG {%%nick%%} :\00304Invaid Request\00315 \00304- Use format SSxEE for (S)eason and (E)pisode\00315"

...

proc pub:tvrage.com.getSummary {nick uhost hand chan text} {

...

   if {![regexp {(.*) (\d+x\d+)} $text -> showname ep]} {
      pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(invalidRequestLine) [array get show]]
      return
   }

...

proc pub:tvrage.com.showinfo {nick uhost hand chan text} {

...

   if {$text==""} {
         pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(showInfoUsage) [array get show]]
         return
   }

4) Now having forced all the output into the PM window, I would now like to use carriage returns in the strings to split the output to be more legibile.

Example string

Code: Select all

set tvrage(showInfoLine) "PRIVMSG {%%nick%%} :\00303Title ::\00315 \00304{%%title%%}\00315\n\00303URL ::\00315 \00304{%%url%%}\00315\n\00303
Premiered ::\00315 \00304{%%premiered%%}\00315\n{%%latest%%}\n{%%next%%}\n\00303Country ::\00315 \00304{%%country%%}\00315\n\00303Status ::\
00315 \00304{%%status%%}\00315"
Addition to code to achieve this

Code: Select all

proc pub:tvrage.com.displayInfo {text {prefix {}} {tosplit {}}} {

...

   # Now split on newlines
   foreach inputline [split $tosplit "\n"] {
      foreach line [wordwrap $inputline $tvrage(nChars) $prefix] {
         putserv $line
      }
   }

As I said at the beginning - GREAT script, saved me a hell of a lot of work. I was about to write one from scratch. Much appreciated that you shared this.

:cap:
G
GaveUp
Op
Posts: 139
Joined: Thu Jan 19, 2006 3:56 am

Post by GaveUp »

Thanks for the code bits. Some of those features had already been implemented in the next version. Those that were not now are. I am laying out plans for one more tweak before posting the next version.
G
GaveUp
Op
Posts: 139
Joined: Thu Jan 19, 2006 3:56 am

Post by GaveUp »

Here it is. The latest version with lots of new features and a bug fix thrown in for good measure.

Code: Select all

####################
#    tvrage.tcl    #
#   v0.8 17Sep06   #
# Coded By: GaveUp #
####################

###################
#   DESCRIPTION   #
#################################################################################
# This script pulls today's or tomorrow's schedule of new shows from tvrage.com #
# Triggers:                                                                     #
#     !today [<country>] -- Display today's schedule                            #
#     !tomorrow [<country>] -- Display tomorrow's schedule                      #
#     !showinfo <show name> -- Display detailed information for <show name>     #
#     !schedule <day> [<country>] -- Display schedule for <day>                 #
#                        <day> can be one of: mon, tue, wed, thu, fri, sat, sun #
#     !summary <show> <episode> -- Display a summary for <episode> of <show>    #
#################################################################################

#############################
# Installation Instructions #
###############################################################################
# Load this script in your eggdrop conf and do a ".chanset <channel> +tv" for #
# every channel you want the script to respond in.                            #
###############################################################################

####################
# Revision History #
#####################################################################
# 0.8 -- +Added gl-style log file parsing and autodisplay of        #
#         summary. Set +tvlog on channels to display in.  Idea      #
#         taken from bin-tv script.                                 #
#        +Added a help trigger.                                     #
#        +Added debug setting.  Useful for error reports.           #
#        +Added support to schedule triggers for multiple           #
#         countries.                                                #
#        +Added options to enable/disable schedules and showinfo.   #
#        *Fixed bug in summary retreiving.                          #
#        +Added debug setting and helper functions to make bug      #
#         reporting easier.  Not all functions currently utilize    #
#         this.  This will be corrected in a future version.        #
#        +Added settings to change flags on binds.  This can be     #
#         to only allow certain users to access commands.           #
#        +Added support to format lines for splitting at an         #
#         arbitrary place. Thanks to Fredgremlin for the code.      #
#        +Added option to set triggers to public or private.        #
#         Thanks to Fredgremlin for the idea.                       #
# 0.7 -- +Added wordwrap class to support wrapping of long lines.   #
#         Thanks to user for posting code in the thread             #
#         http://forum.egghelp.org/viewtopic.php?t=6690 which       #
#         provided a base for the wordwrap function in this script. #
#        +Added !summary trigger to pull a summary for a given      #
#         episode.  Usage: !summary <show title> <episode number>   #
#         <episode number> must be in the format of WWxYY where WW  #
#         is the season number and WW is the episode number.        #
#        *'Long Line' problem fixed with wordwrap code              #
#        *Fixed minor aesthetic and formatting issues               #
# 0.6 -- *Patch to deal with non-displayable characters that caused #
#         crashes                                                   #
#        +Added Templating Support to allow for customizing of      #
#         output                                                    #
#        +Moved hardcoded variables to global settings.  This will  #
#         make it easier to deal with changes that might occur to   #
#         the website info is pulled from                           #
# 0.5 -- *Yet more regex tweaks                                     #
# 0.4 -- *more tweaks to regex                                      #
#        *removed ncgi requirement                                  #
# 0.3 -- *fixed last time of 7th day now displayed                  #
#        *tweaked regex to catch some programs it was missing       # 
# 0.2 -- +!showinfo trigger for detailed show info and next/last ep #
#        +!schedule for 7 day schedule                              #
#        *fixed errors in various regex                             #
# 0.1 -- Initial Release                                            #
#                                                                   #
# + added   - removed   * fixed/changed                             #
#####################################################################

########
# TODO #
########################################################
# *Nothing?                                            #
########################################################



####################
### Begin Config ###
####################


### Bind Settings ###

# Trigger to show today's schedule
set tvrage(todayTrigger) "!today"

# Trigger to show tomorrow's schedule
set tvrage(tomorrowTrigger) "!tomorrow"

# Trigger to show information about a show
set tvrage(showinfoTrigger) "!showinfo"

# Trigger to get schedule for specified day
set tvrage(scheduleTrigger) "!schedule"

# Trigger to get summary of an episode of a show
set tvrage(summaryTrigger) "!summary"

# Trigger to show a list of available countries for schedules.
set tvrage(availableCountriesTrigger) "!availablecountries"

# Trigger to get help for script
set tvrage(helpTrigger) "!tvhelp"

# Flags for today trigger bind (see eggdrop docs on "bind" command for more information)
set tvrage(todayFlags) "-"

# Flags for tomorrow trigger bind (see eggdrop docs on "bind" command for more information)
set tvrage(tomorrowFlags) "-"

# Flags for schedule trigger bind (see eggdrop docs on "bind" command for more information)
set tvrage(scheduleFlags) "-"

# Flags for available countries trigger bind (see eggdrop docs on "bind" command for more information)
set tvrage(availableCountriesFlags) "-"

# Flags for showinfo trigger bind (see eggdrop docs on "bind" command for more information)
set tvrage(showinfoFlags) "-"

# Flags for help trigger bind (see eggdrop docs on "bind" command for more information)
set tvrage(helpFlags) "-"

# Flags for summary trigger bind (see eggdrop docs on "bind" command for more information)
set tvrage(summaryFlags) "-"


### Formatting Settings ###

# Separator between season number and episode number
set tvrage(seasonEpisodeSeparator) "x"

# The following formatting settings support place holders.  These placeholders
# represent pieces of the data to be displayed.  The following place holders
# are supported:
# 			{%%chan%%} -- Channel that trigger request came from
#			{%%nick%%} -- Nick that made trigger request 
#        {%%title%%} -- Show name 
#        {%%url%%} -- URL to detailed show info (only available in showinfo)
#			{%%premiered%%} -- Year show premiered (only available in showinfo)
#			{%%latest%%} -- Wrapper for latestEpFormat/latestEpNoExistFormat settings (only available in showinfo)
#			{%%next%%} -- Wrapper for nextEpFormat/nextEpNoExistFormat settings (only available in showinfo)
#			{%%country%%} -- Country show originated in (only available in showinfo)
#			{%%status%%} -- Status of show (cancelled, returning series, etc) (only available in showinfo)
#			{%%nextSeason%%} -- Season number of next episode to air (only available in showinfo)
#			{%%nextEpisode%%} -- Episode number of next episode to air (only available in showinfo)
#			{%%nextTitle%%} -- Title of next episode to air (only available in showinfo)
#			{%%nextDate%%} -- Date of next episode to air (only available in showinfo)
#			{%%latestSeason%%} -- Season number of last episode to air (only available in showinfo)
#			{%%latestEpisode%%} -- Episode number of last episode to air (only available in showinfo)
#			{%%latestTitle%%} -- Title of last episode to air (only available in showinfo)
#			{%%latestDate%%} -- Date of last episode to air (only available in showinfo)
#			{%%date%%} -- Date of schedule being displayed (only available in schedule)
#			{%%time%%} -- Time of airing (when displaying a schedule) (only available in schedule)
#			{%%network%%} -- Network show airs on (only available in schedule)
#			{%%epnum%%} -- "Season"x"Episode" of show airing (only available in schedule)
#			{%%scheduleLine%%} -- Line in schedule listing (only available in schedule)
#        {%%scheduleShowSeparator%%} -- Separator between shows in a schedule listing (only available in schedule)
#        {%%epSeason%%} -- Season of Episode (only available in summary)
#        {%%epNumber%%} -- Episode Number of show (only available in summary)
#        {%%epTitle%%} -- Title of episode (only available in summary)
#        {%%epDate%%} -- Date of first airing of episode (only available in summary)
#        {%%summary%%} -- Summary of episode (only available in summary)
#        {%%dirname%%} -- Name of directory being looked up. (only available in tvlogLine and tvlogNoFoundLine)
#        {%%request%%} -- Show raw request for summary.  (only available in summary)
#        {%%todayTrigger%%} -- Trigger to show schedule for today.  (only available in help format lines)
#        {%%tomorrowTrigger%%} -- Trigger to show schedule for tomorrow.  (only available in help format lines)
#        {%%scheduleTrigger%%} -- Trigger to show schedule for a variable day.  (only available in help format lines)
#        {%%showinfoTrigger%%} -- Trigger to show information on a specified show.  (only available in help format lines)
#        {%%helpTrigger%%} -- Trigger to show help information.  (only available in help format lines)
#        {%%summaryTrigger%%} -- Trigger to show summary of a show.  (only available in help format lines)
#        {%%versionLine%%} -- Version line with name of script and version number.  (only available in help format lines)
#        {%%availableCountries%%} -- List of available countries.  (only available in help format lines)
#        {%%upperAvailableCountries%%} -- List of available countries in uppercase.  (only available in help format lines)
#        {%%lowerAvailableCountries%%} -- List of available countries in lowercase.  (only available in help format lines)

# Formatting of info displayed on !showinfo
set tvrage(showInfoLine) "PRIVMSG {%%chan%%} :\00303Title ::\00315 \00304{%%title%%}\00315 \00308<>\00315 \00303URL ::\00315 \00304{%%url%%}\00315 \00308<>\00315 \00303Premiered ::\00315 \00304{%%premiered%%}\00315 \00308<>\00315 {%%latest%%} \00308<>\00315 {%%next%%} \00308<>\00315 \00303Country ::\00315 \00304{%%country%%}\00315 \00308<>\00315 \00303Status ::\00315 \00304{%%status%%}\00315"

# Formatting of next episode to air info displayed on !showinfo
set tvrage(nextEpFormat) "\00303Next Episode ::\00315 \00304{%%nextSeason%%}{%%seasonEpisodeSeparator%%}{%%nextEpisode%%} - {%%nextTitle%%} ({%%nextDate%%})\00315"

# Formatting when there is no episode that has not aired (ie: after a series ends or before new season episodes are announced)
set tvrage(nextEpNoExistFormat) "\00303Next Episode ::\00315 \00304N/A\00315"

# Formatting of last episode to air info displayed on !showinfo
set tvrage(latestEpFormat) "\00303Latest Episode ::\00315 \00304{%%latestSeason%%}{%%seasonEpisodeSeparator%%}{%%latestEpisode%%} - {%%latestTitle%%} ({%%latestDate%%})\00315"

# Formatting when no previous episode has aired (ie: before a show premieres)
set tvrage(latestEpNoExistFormat) "\00303Latest Episode ::\00315 \00304N/A\00315"

# Header to display before showing a schedule.  
set tvrage(scheduleHeader) "PRIVMSG {%%chan%%} :\00303New TV Shows for {%%date%%} ***All Times in EST/EDT***\00315"

# Format of the time display for each line in a schedule listing
set tvrage(scheduleTimeFormat) "\002{%%time%%}:\002 "

# Format of a show in a schedule listing
set tvrage(scheduleEpisodeFormat) "\00304{%%network%%}\00315 - \00314{%%title%%} {%%epnum%%}\00315 {%%scheduleShowSeparator%%} "

# Separator between episodes in a schedule listing
set tvrage(scheduleShowSeparator) "<>"

# Format of a schedule Line (should be used primarily to change from a public message, to private message, etc)
set tvrage(scheduleLine) "PRIVMSG {%%chan%%} :{%%scheduleLine%%}"

# Format of info to show when !showinfo does not find the requested show
set tvrage(noShowLine) "PRIVMSG {%%chan%%} :\00303No Show Results Were Found For \"\00315\00304{%%title%%}\00315\00303\"\00315"

# Format of info to show when !summary finds a summary
set tvrage(summaryLine) "PRIVMSG {%%chan%%} :\00303Show ::\00315 \00304{%%title%%}\00315 \00308<>\00315 \00303Episode ::\00315 \00304{%%epSeason%%}{%%seasonEpisodeSeparator%%}{%%epNumber%%} - {%%epTitle%%} ({%%epDate%%})\00315 \00308<>\00315 \00303Summary:\00315 \00304{%%summary%%}\00315 \00308<>\00315 \00303Episode URL ::\00315 \00304{%%url%%}\00315"

# Format of summary request invalid.
set tvrage(summaryInvalidFormatLine) "PRIVMSG {%%chan%%} :\00303Invalid format \"\00315\00304{%%request%%}\00315\00303\"\00315"

# Format of info to show on data from tvlog
set tvrage(tvlogLine) "PRIVMSG {%%chan%%} :\00303Show ::\00315 \00304{%%title%%}\00315 \00308<>\00315 \00303Episode ::\00315 \00304{%%epSeason%%}{%%seasonEpisodeSeparator%%}{%%epNumber%%} - {%%epTitle%%} ({%%epDate%%})\00315 \00308<>\00315 \00303Summary:\00315 \00304{%%summary%%}\00315 \00308<>\00315 \00303Episode URL ::\00315 \00304{%%url%%}\00315"

# Format of info to show on data from tvlog when no info could be found.
set tvrage(tvlogNoFoundLine) "PRIVMSG {%%chan%%} :\00303Information on \"\00315\00304{%%dirname%%}\00315\00303\" not found.\00315"

# Format of Header for !tvhelp
set tvrage(helpHeader) "PRIVMSG {%%nick%%} :{%%versionLine%%}"

# Format of Help shown for schedule
set tvrage(helpSchedule) "PRIVMSG {%%nick%%} :{%%scheduleTrigger%%} <day> -- Show schedule for <day>.  Day must be: mon, tue, wed, thu, fri, sat, sun."

# Format of Help shown for showinfo
set tvrage(helpShowinfo) "PRIVMSG {%%nick%%} :{%%showinfoTrigger%%} <show> \[<country>\]-- Show info on <show>.  Country is optional.  Valid countries are {%%upperAvailableCountries%%}."

# Format of Help shown for today
set tvrage(helpToday) "PRIVMSG {%%nick%%} :{%%todayTrigger%%} \[<country>\] -- Show schedule for today.  Country is optional.  Valid countries are {%%upperAvailableCountries%%}."

# Format of Help shown for tomorrow
set tvrage(helpTomorrow) "PRIVMSG {%%nick%%} :{%%tomorrowTrigger%%} \[<country>\] -- Show schedule for tomorrow.  Country is optional.  Valid countries are {%%upperAvailableCountries%%}."

# Format of Help shown for summary
set tvrage(helpSummary) "PRIVMSG {%%nick%%} :{%%summaryTrigger%%} <show> <ep> -- Show summary of <ep> of <show>.  <ep> must be in the format of SeasonxEpisode (ie: 2x15 is Season 2 Episode 15)."

# Format of Help shown for help
set tvrage(helpHelp) "PRIVMSG {%%nick%%} :{%%helpTrigger%%} -- Show this help."

# Format of error to show when an invalid country is specified
set tvrage(invalidCountry) "PRIVMSG {%%chan%%} :\00303\"{%%country%%}\"\00315 \00304is an invalid country.\00315"

# Format of message to show when a list of available countries are requested.
set tvrage(availableCountriesLine) "PRIVMSG {%%chan%%} :\00304Available countries are:\00315 \00303{%%upperAvailableCountries%%}\00315"

### Misc. Settings ###

# Enable(1)/Disable(0) !schedule,!today,!tomorrow triggers.
set tvrage(enableSchedule) 1

# Enable(1)/Disable(0) !showinfo trigger.
set tvrage(enableShowInfo) 1

# Enable(1)/Disable(0) !summary trigger.
set tvrage(enableSummary) 1

# Enable(1)/Disable(0) !tvhelp trigger.
set tvrage(enableHelp) 1

# Set triggers to pub(1) or msg(2).
set tvrage(pubTriggers) 1

# Split Lines at nChars length
set tvrage(nChars) 425

# Default Country for !schedule/!today/!tomorrow
set tvrage(defaultCountry) "US"

# Available Countries (space separated)
set tvrage(availableCountries) "US CA GB AU"

# Use NCGI package?
# Set to 1 to use NCGI or 0 to use inbuilt function (0 recommended)
set tvrage(useNCGI) 0

# URL to grab schedule from
# Do NOT change this unless you know what you're doing
set tvrage(scheduleurl) "http://www.tvrage.com/quickschedule.php?country="

# URL to grab show info from
# Do NOT change this unless you know what you're doing
set tvrage(showinfourl) "http://www.tvrage.com/quickinfo.php"

# Debug?
set tvrage(debug) 0

# Enable log file parsing
set tvrage(enableTVLog) 0

# Full path to log file
set tvrage(tvlog) ""

# Interval (in seconds) to check log file for updates
set tvrage(tvlogTimerDelay) 3

##################
### End Config ###
##################


###################################
### DO NOT EDIT BELOW THIS LINE ###
###################################
set tvrage(version) "v0.8"
set tvrage(versionLine) "TVRage.com Primetime Schedule Script $tvrage(version)"

if {$tvrage(pubTriggers)} {
   if {$tvrage(enableSchedule)} {
      bind pub $tvrage(todayFlags) $tvrage(todayTrigger) pub:tvrage.com.today
      bind pub $tvrage(tomorrowFlags) $tvrage(tomorrowTrigger) pub:tvrage.com.tomorrow
      bind pub $tvrage(scheduleFlags) $tvrage(scheduleTrigger) pub:tvrage.com.schedule
      bind pub $tvrage(availableCountriesFlags) $tvrage(availableCountriesTrigger) pub:tvrage.com.availableCountries
   }
   if {$tvrage(enableShowInfo)} {
      bind pub $tvrage(showinfoFlags) $tvrage(showinfoTrigger) pub:tvrage.com.showinfo
   }
   if {$tvrage(enableHelp)} {
      bind pub $tvrage(helpFlags) $tvrage(helpTrigger) pub:tvrage.com.help
   }
   if {$tvrage(enableSummary)} {
      bind pub $tvrage(summaryFlags) $tvrage(summaryTrigger) pub:tvrage.com.getSummary
   }
} else {
   if {$tvrage(enableSchedule)} {
      bind msg $tvrage(todayFlags) $tvrage(todayTrigger) pub:tvrage.com.today
      bind msg $tvrage(tomorrowFlags) $tvrage(tomorrowTrigger) pub:tvrage.com.tomorrow
      bind msg $tvrage(scheduleFlags) $tvrage(scheduleTrigger) pub:tvrage.com.schedule
      bind msg $tvrage(availableCountriesFlags) $tvrage(availableCountriesTrigger) pub:tvrage.com.availableCountries
   }
   if {$tvrage(enableShowInfo)} {
      bind msg $tvrage(showinfoFlags) $tvrage(showinfoTrigger) pub:tvrage.com.showinfo
   }
   if {$tvrage(enableHelp)} {
      bind msg $tvrage(helpFlags) $tvrage(helpTrigger) pub:tvrage.com.help
   }
   if {$tvrage(enableSummary)} {
      bind msg $tvrage(summaryFlags) $tvrage(summaryTrigger) pub:tvrage.com.getSummary
   }
}

package require http

if {$tvrage(useNCGI)} {
	package require ncgi
}

setudef flag tv
setudef flag tvlog

proc pub:tvrage.com.init {} {
	global tvrage


	if {[info exists tvrage(tvlogTImer)]} {
		if {[catch { killutimer $tvrage(tvlogTimer) } message] } {
			pub:tvrage.com.debug $message
		}
	}

	if { $tvrage(enableTVLog) } {
		if { [file exists "$tvrage(tvlog)"] } {
			set tvrage(tvlogSize) [file size $tvrage(tvlog)]
			set tvrage(tvlogTimer) [utimer $tvrage(tvlogTimerDelay) "pub:tvrage.com.readTVLog"]
		} else {
			pub:tvrage.com.debug "ERROR: pub:tvrage.com.init{}: \"$tvrage(tvlog)\" does not exist"
		}
	}		
}
      
proc pub:tvrage.com.availableCountries {nick uhost hand chan text} {
   global tvrage

   if ![channel get $chan tv] { return }

   set show(upperAvailableCountries) [string toupper $tvrage(availableCountries)]
   set show(lowerAvailableCountries) [string tolower $tvrage(availableCountries)]
   set show(availableCountries) $tvrage(availableCountries)
   set show(chan) $chan
   set show(nick) $nick

   pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(availableCountriesLine)  [array get show]]
}

proc pub:tvrage.com.help {nick uhost hand chan text} {
	global tvrage

	if ![channel get $chan tv] { return }

	set show(nick) $nick
	set show(chan) $chan
	set show(scheduleTrigger) $tvrage(scheduleTrigger)
	set show(showinfoTrigger) $tvrage(showinfoTrigger)
	set show(todayTrigger) $tvrage(todayTrigger)
	set show(tomorrowTrigger) $tvrage(tomorrowTrigger)
	set show(summaryTrigger) $tvrage(summaryTrigger)
	set show(helpTrigger) $tvrage(helpTrigger)
	set show(version) $tvrage(version)
	set show(versionLine) [pub:tvrage.com.templateParser $tvrage(versionLine) [array get show]]
   set show(upperAvailableCountries) [string toupper $tvrage(availableCountries)]
   set show(lowerAvailableCountries) [string tolower $tvrage(availableCountries)]
   set show(availableCountries) $tvrage(availableCountries)

	pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(helpHeader) [array get show]]

   if {$tvrage(enableSchedule)} {
   	pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(helpSchedule) [array get show]]
	   pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(helpToday) [array get show]]
   	pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(helpTomorrow) [array get show]]
   }

   if {$tvrage(enableShowInfo)} { pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(helpShowinfo) [array get show]] }
	if {$tvrage(enableSummary)} { pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(helpSummary) [array get show]] }
	pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(helpHelp) [array get show]]
}

proc pub:tvrage.com.readTVLog {} {
	global tvrage
	
	set tvrage(tvlogTimer) [utimer $tvrage(tvlogTimerDelay) "pub:tvrage.com.readTVLog"]
	set curSize [file size $tvrage(tvlog)]
	if { $curSize == $tvrage(tvlogSize) } { return 0 }
	if { $curSize < $tvrage(tvlogSize) } {
		set tv(tvlogSize) $curSize
		pub:tvrage.com.debug "INFO: pub:tvrage.com.readTVLogP{}: $tvrage(tvlog) smaller than last pub:tvrage.com.readTVLog{}."
	}
	if { [catch { set fh [open $tvrage(tvlog) r] }] } {
		pub:tvrage.com.debug "ERROR: pub:tvrage.com.readTVLog{}: Could not open $tvrage(tvlog) for reading."
		return 0
	}

	seek $fh $tvrage(tvlogSize)
	while { ![eof $fh] } {
		if { [catch { set line [string trimright [gets $fh]] }] } {
			pub:tvrage.com.debug "ERROR: pub:tvrage.com.readTVLog{}: Could not read from $tvrage(tvlog)."
			break
		}
		if { [string index $line 0] == "#" } { continue }
		if { [llength $line] == 0 } { continue }

		if { [lindex [split $line " "] 5] == "NEWDIR:" } {
			set info [exec basename [lindex [split $line " "] 6]]
			set info [string trimright $info "\""]
			pub:tvrage.com.getInfo $info
		}
	}

	close $fh
	set tvrage(tvlogSize) [file size $tvrage(tvlog)]
	return 0
}

proc pub:tvrage.com.getInfo {info} {
	global tvrage

	set show(dirname) $info
	set pattern1 {^([\w\d\.\_\-]+)\.S([\d]{1,2})E([\d]{1,2})}
	set pattern2 {^([\w\d\.\_\-]+)\.([\d]{1,2})x([\d]{1,2})}

	if { ![regexp "$pattern1" $info => title season episode] && ![regexp "$pattern2" $info => title season episode] } {
		tv:debug "ERROR: pub:tvrage.com.getInfo{}: Unknown Formatting of $info."
		return
	}

	regsub -all -- {\.} $title " " title
	regsub -all -- {\_} $title " " title
	set sxep [pub:tvrage.com.convertToSxEp $season $episode]
	
	pub:tvrage.com.getEpisodeInfo $title $sxep

   foreach chan [channels] {
		if {[channel get $chan tvlog] && [botonchan $chan]} {
			set show(chan) $chan
			if { !$show(found) } {
				pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(tvlogNoFoundLine) [array get show]]
			} else {
				pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(tvlogLine) [array get show]]
			}
		}
	}
}

proc pub:tvrage.com.convertToSxEp {season episode} {
	set season [string trimleft $season "0"]
	set episode [string trimleft $season "0"]

	if { $episode < 10 } {
		set episode "0$episode"
	}
	
	return [join [list $season "x" $episode] ""]
}

proc pub:tvrage.com.debug {lines} {
	global tvrage

	if { $tvrage(debug) } {
		foreach line [split $lines "\n"] {
			putlog "TVRage: $line"
		}
	}
}

proc pub:tvrage.com.wordwrap {str {len 200} {prefix {}} {splitChr { }}} {
	set out {}
	set cur $prefix
	set i 0
	foreach word [split [set str][unset str] $splitChr] {
		if {[incr i [string len $word]]>$len} {
			lappend out [join $cur $splitChr]
			if {[regexp {^.*(\003\d\d)} $cur -> lastColor]} {
				set cur [join [list $prefix $lastColor $word] ""]
			} else {
				set cur [join [list $prefix $word] ""]
			}
			set i [string len $word]
		} {
			lappend cur $word
		}
		incr i
	}
	lappend out [join $cur $splitChr]
}

proc pub:tvrage.com.displayInfo {text {prefix {}} {tosplit {}}} {
	global tvrage
	
	if {([string len $prefix] == 0) && ([string len $tosplit] == 0)} {
		regexp {^(.*?:)(.*)$} $text -> prefix tosplit
	} elseif {[string len $prefix] == 0} {
		regexp {^(.*?:)(.*)$} $text -> prefix ->
	} elseif {[string len $tosplit] == 0} {
		regexp {^(.*?:)(.*)$} $text -> -> tosplit
	}
	
	foreach inputLine [split $tosplit "\n"] {
      foreach line [pub:tvrage.com.wordwrap $inputLine $tvrage(nChars) $prefix] {
	   	putserv $line
	   }
   }
}

proc pub:tvrage.com.getEpisodeInfo {showname ep} {
	global tvrage

	upvar show show

	if {$tvrage(useNCGI)} {
	set token [http::geturl [join [list $tvrage(showinfourl) "?show=" [ncgi::encode [string trimleft $showname]] "&ep=" [ncgi::encode [string trimleft $ep]]] ""]]
   } else {
      set token [http::geturl [join [list $tvrage(showinfourl) "?show=" [parse:tvrage.com.encodeURL [string trimleft $showname]] "&ep=" [parse:tvrage.com.encodeURL [string trimleft $ep]]] ""]]
   }
   set data [http::data $token]
   http::cleanup $token

   foreach line [split $data \n] {
		if {[regexp {^No Show Results Were Found For \"(.*)\"$} $line -> show(title)]} {
			set show(found) 0
			return
		}
 	   if {[regexp {^Episode URL@(.*)$} $line -> match]} { 
		   set show(url) $match 
		}
		if {[regexp {^Show Name@(.*)$} $line -> match]} { set show(title) $match }
		if {[regexp {^Episode Info@(\d+)x(\d+)\^(.*)\^([\w\/]+)$} $line -> season episode eptitle epDate]} { 
			set show(latest) 1
			set show(epTitle) $eptitle
			set show(epSeason) $season
			set show(epNumber) $episode
			set show(epDate) $epDate
			set show(seasonEpisodeSeparator) $tvrage(seasonEpisodeSeparator)
		}
	}

	set token [http::geturl $show(url)]
	set data [http::data $token]
	http::cleanup $token

	regsub -all "\n" $data "" data
	regsub -all "<br>" $data "" data
   if {[regexp "<table width=\'98%\' align='center'><tr><td>(.*?)</td></tr></table>" $line -> match]} { set show(summary) $match }	
	
	set show(found) 1
}

proc pub:tvrage.com.getSummary {nick uhost hand chan text} {
	global tvrage

	if ![channel get $chan tv] return

   set show(chan) $chan
   set show(nick) $nick
	set show(request) $text
   
	if {![regexp {(.*) (\d+x\d+)} $text -> showname ep]} {
		pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(summaryInvalidFormatLine) [array get show]]
		return
	}
	
   pub:tvrage.com.getEpisodeInfo $showname $ep
  
   if {$show(found)} {
		pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(summaryLine) [array get show]]
	} else {
		pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(noShowLine) [array get show]]
	}
}

proc pub:tvrage.com.templateParser {template info} {
	set filled $template
	foreach {key value} $info {
		regsub -all {\&} $value {\\&} value
		regsub -all "\{\%\%$key\%\%\}" $filled $value filled
	}

	return $filled
}

proc pub:tvrage.com.verifyCountry {text} {
   global tvrage

   foreach co [split $tvrage(availableCountries) { }] {
      if {[string tolower $text] == [string tolower $co]} {
         return true
      }
   }

   return false
}

proc pub:tvrage.com.schedule {nick uhost hand chan text} {
   global tvrage
      
	set seconds [clock seconds]
	set days(sun) 0
	set days(mon) 1
	set days(tue) 2
	set days(wed) 3
	set days(thu) 4
	set days(fri) 5
	set days(sat) 6

   set show(nick) $nick
   set show(chan) $chan
   set desiredDay [lindex $text 0]
   set show(country) [lindex $text 1]

   if {[string length $show(country)] == 0} { set show(country) $tvrage(defaultCountry) }
   
   if ![pub:tvrage.com.verifyCountry $show(country)] { 
	   pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(invalidCountry) [array get show]]
      return
   }

	if ![info exist days([string tolower $desiredDay])] return 

	set currDay [clock format $seconds -format "%w"]
	
	if {$currDay > $days([string tolower $desiredDay])} {
		parse:tvrage.com $nick $uhost $hand $chan $text [expr (7 - $currDay) + $days([string tolower $text])] $show(country)
	} else {
		parse:tvrage.com $nick $uhost $hand $chan $text [expr $days([string tolower $desiredDay]) - $currDay] $show(country)
	}
}
		

proc pub:tvrage.com.today {nick uhost hand chan text} {
   global tvrage

   set show(nick) $nick
   set show(chan) $chan
   set show(country) [lindex $text 0]

   if {[string length $show(country)] == 0} { set show(country) $tvrage(defaultCountry) }
   
   if ![pub:tvrage.com.verifyCountry $show(country)] { 
	   pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(invalidCountry) [array get show]]
      return
   }
   
	parse:tvrage.com $nick $uhost $hand $chan $text "0" $show(country)
}

proc pub:tvrage.com.tomorrow {nick uhost hand chan text} {
	global tvrage
      
   set show(nick) $nick
   set show(chan) $chan
   set show(country) [lindex $text 0]

   if {[string length $show(country)] == 0} { set show(country) $tvrage(defaultCountry) }
   
   if ![pub:tvrage.com.verifyCountry $show(country)] { 
	   pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(invalidCountry) [array get show]]
      return
   }
   
   parse:tvrage.com $nick $uhost $hand $chan $text "1" $show(country)
}

proc parse:tvrage.com.encodeURL {str} {
	set str [string map {" " +} $str] 
	foreach c [split $str {}] {
	   if {$c == "+" || [string is alnum $c]} {append x $c} {
	      binary scan $c H2 c; append x %$c
	   }
	} 

	return $x
}

proc pub:tvrage.com.getShowInfo {text} {
	global tvrage

	upvar show show

	if {$tvrage(useNCGI)} {
		set token [http::geturl [join [list $tvrage(showinfourl) "?show=" [ncgi::encode [string trimleft $text]]] ""]]
	} else {
		set token [http::geturl [join [list $tvrage(showinfourl) "?show=" [parse:tvrage.com.encodeURL [string trimleft $text]]] ""]]
	}
	set data [http::data $token]
	http::cleanup $token
	set show(title) ""

	foreach line [split $data \n] {
		regsub -all {\x92} $line {'} line
		if {[regexp {^No Show Results Were Found For \"(.*)\"$} $line -> show(title)]} {
			set show(found) 0
			return show
		}
		if {[regexp {^Show Name@(.*)$} $line -> match]} { set show(title) $match }
		if {[regexp {^Show URL@(.*)$} $line -> match]} { set show(url) $match }
		if {[regexp {^Premiered@(.*)$} $line -> match]} { set show(premiered) $match }
		if {[regexp {^Latest Episode@(\d+)x(\d+)\^(.*)\^([\w\/]+)$} $line -> season episode eptitle epDate]} { 
			set show(latest) 1
			set show(latestTitle) $eptitle
			set show(latestSeason) $season
			set show(latestEpisode) $episode
			set show(latestDate) $epDate
			set show(latestSeparator) $tvrage(seasonEpisodeSeparator)
		}
		if {[regexp {^Next Episode@(\d+)x(\d+)\^(.*)\^([\w\/]+)$} $line -> season episode eptitle epDate]} { 
			set show(next) 1
			set show(nextTitle) $eptitle
			set show(nextSeason) $season
			set show(nextEpisode) $episode
			set show(nextDate) $epDate
			set show(nextSeparator) $tvrage(seasonEpisodeSeparator)
		}
		if {[regexp {^Country@(.*)$} $line -> match]} { set show(country) $match }
		if {[regexp {^Status@(.*)$} $line -> match]} { set show(status) $match }
		if {[regexp {^Classification@(.*)$} $line -> match]} { set show(class) $match }
	}

	if ![info exist show(latest)] { 
		set show(latest) 0
		set show(latestTitle) ""
		set show(latestSeason) ""
		set show(latestEpisode) "N/A"
		set show(latestDate) ""
		set show(latestSeparator) ""
	}

	if ![info exist show(next)] { 
		set show(next) 0
		set show(nextTitle) ""
		set show(nextSeason) ""
		set show(nextEpisode) "N/A"
		set show(nextDate) ""
		set show(nextSeparator) ""
	}

	set show(found) 1
}
proc pub:tvrage.com.showinfo {nick uhost hand chan text} {
	global tvrage

	if ![channel get $chan tv] return

	set show(chan) $chan
	set show(nick) $nick
	
	pub:tvrage.com.getShowInfo $text

	set show(seasonEpisodeSeparator) $tvrage(seasonEpisodeSeparator)
   
	if {!$show(found)} {
		pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(noShowLine) [array get show]]
		return
	}
	
	if {$show(next)} {
		set show(next) [pub:tvrage.com.templateParser $tvrage(nextEpFormat) [array get show]]
	} else {
		set show(next) [pub:tvrage.com.templateParser $tvrage(nextEpNoExistFormat) [array get show]]
	}

	if {$show(latest)} {
		set show(latest) [pub:tvrage.com.templateParser $tvrage(latestEpFormat) [array get show]]
	} else {
		set show(latest) [pub:tvrage.com.templateParser $tvrage(latestEpNoExistFormat) [array get show]]
	}

	pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(showInfoLine) [array get show]]
}
		
proc parse:tvrage.com {nick uhost hand chan text when country} {
	global tvrage

	if ![channel get $chan tv] return
	set token [http::geturl [join [list $tvrage(scheduleurl) $country] ""]]
	set data [http::data $token]
	http::cleanup $token
	set date ""
	set systemTime [clock seconds]
	set currentTime ""
	set parsing 0
	set currentOutput ""
	set gotTime 0
	set neededDate ""
	set neof 1

	set systemTime [expr "$systemTime + ($when * 86400)"]
	set neededDate [clock format $systemTime -format "%A, %d %b %Y"]

	set show(chan) $chan
	set show(nick) $nick
	set show(scheduleShowSeparator) $tvrage(scheduleShowSeparator)

	foreach line [split $data \n] {
		if {[regexp {^\[DAY\]([\w\, ]+)\[\/DAY\]$} $line -> date]} {
			if {$parsing == 1} {
				break;
			}
			
			if {$date == $neededDate} {
				set show(date) $date
				pub:tvrage.com.displayInfo [pub:tvrage.com.templateParser $tvrage(scheduleHeader) [array get show]]
				set parsing 1
			}
		}

		if {$parsing} {
			if {[regexp {^\[TIME\]([\w\: ]+)\[\/TIME\]$} $line -> show(time)]} {
				if {$gotTime} {
					set show(scheduleLine) [string trim $currentOutput $tvrage(scheduleShowSeparator)]
					set outputLine [pub:tvrage.com.templateParser $tvrage(scheduleLine) [array get show]]
					regexp {^(.*?:.*\d\d:\d\d [ap]m:.*? )(.*)$} $outputLine -> prefix tosplit
					pub:tvrage.com.displayInfo $outputLine $prefix $tosplit
					unset prefix
					unset tosplit
					set currentOutput ""
				}

				set currentOutput [pub:tvrage.com.templateParser $tvrage(scheduleTimeFormat) [array get show]]
				set gotTime 1
			}

			regsub -all {\x92} $line {'} line
			if {[regexp {^\[SHOW\]([ \w\&\!]+)\^([\,\.\-\(\)\#\w \'\`\:&\!\/]+)\^([\dx]+)\^([\w\\\/\:\.\-]+)\[\/SHOW\]$} $line -> show(network) show(title) show(epnum) show(url)]} {
				set currentOutput [concat $currentOutput [pub:tvrage.com.templateParser $tvrage(scheduleEpisodeFormat) [array get show]]]
			}
		}
	}

	if {$currentOutput != ""} {
		set show(scheduleLine) [string trim $currentOutput $tvrage(scheduleShowSeparator)]
		set outputLine [pub:tvrage.com.templateParser $tvrage(scheduleLine) [array get show]]
		regexp {^(.*?:.*\d\d:\d\d [ap]m:.*? )(.*)$} $outputLine -> prefix tosplit
		pub:tvrage.com.displayInfo $outputLine $prefix $tosplit
		unset prefix
		unset tosplit
	}
}

pub:tvrage.com.init
putlog [pub:tvrage.com.templateParser $tvrage(versionLine) [array get tvrage]]
User avatar
rosc2112
Revered One
Posts: 1454
Joined: Sun Feb 19, 2006 8:36 pm
Location: Northeast Pennsylvania

Post by rosc2112 »

Hiya, just wanted to ask if there's a url for downloading or if the script will be available from the tcl archive, it's a bit cumbersome to cut/paste it with the word wrap from here.

Tnx :)
G
GaveUp
Op
Posts: 139
Joined: Thu Jan 19, 2006 3:56 am

Post by GaveUp »

At some point I'll submit it to the archive. Right now things are changing to rapidly to make the archive a good idea. An offsite place to store the latest version(s) has come to mind, but as I lack a place to do this and am not a fan of the free hosts out there it'll have to be something for the future.
T
Taz
Voice
Posts: 9
Joined: Sun Oct 23, 2005 10:18 pm

Post by Taz »

:D Great job bud, WD indeed. Truely appreciate your effort and more so your selflessness to contribute to the less knowledgable of the eggy community. A great bit of scripting if I may add also. I personaly have not needed to modify your code for my own personal use. I hope ALL peeps that enjoy your work and use it daily let you know also that they appreciate your work.

I would love to shout out to all the submiting peeps! I just do not have the time to try or use their scripts, but you that do submit are wonderful additions to a great site. :D
s
silver
Voice
Posts: 8
Joined: Tue Apr 18, 2006 11:09 pm

Post by silver »

VERY nice :)

one tiny thing tho...

Code: Select all

set tvrage(showInfoLine) "PRIVMSG {%%chan%%} :\00303Title... etc
outputs :

Code: Select all

<botnick>  Title :: ER
so an extra space before Title
its cuz putserv $line in displayInfo makes this:

Code: Select all

PRIVMSG #chan : Title
all output has the extra space, except for !today
i'd like that space gone :)
i put

Code: Select all

         regsub -all { : } $line { :} line
before the putserv, but it isnt ideal solution ;)

also a small addition

change

Code: Select all

      if {[regexp {^Classification@(.*)$} $line -> match]} { set show(class) $match }
to

Code: Select all

      if {[regexp {^Classification@(.*)$} $line -> match]} { set show(class) $match }
      if {[regexp {^Genres@(.*)$} $line -> match]} { set show(genres) $match }
and you have {%%genres%%}.. new on tvrage


thnx for your script!

--edit--
summary still doesnt work for me btw.. getting {%%summary%%} in bot output
s
silver
Voice
Posts: 8
Joined: Tue Apr 18, 2006 11:09 pm

Post by silver »

oh one more thing hehe
support for diff timezones would be nice... so !today can show times in GMT+1 for example
G
GaveUp
Op
Posts: 139
Joined: Thu Jan 19, 2006 3:56 am

Post by GaveUp »

Thanks for reporting the extra space bug and the new genre's feature. The former has now been fixed. The latter has now been implemented and I'm looking at a way to remove the dependance of updating the code as much as possible to implement the new features they might add like the Genre's trait. The summary bug I already knew about and have fixed. It was a result of changing the code around to deal with another fix, how this bug got through me I'm not quite sure but it did and is fixed in the next version.

The timezones option has been mentioned before, but it's a feature that requires a quite a bit of work to add. The 'around midnight' times make things really sketchy and the fact that it's not a straight addition/subtraction to the time also complicates matters. The feature has not been completely ruled out but due to the amount of work required for it it's pretty much been put on the backest of back burners. Pretty much unless someone submits a patch for it (that isn't a quick hack) I don't really see it happening.

The new version needs a little more updating to the documentation, but otherwise is pretty much ready to go. The big hold up is because of the new structure of the script posting it on code tags is impractical so I'm just trying to find a small amount of webspace to use to post the script.

Just as a teaser here's the changelog as it currently stands for 0.9

Code: Select all

*Fixed 'extra space' at start of some lines.
+Added support for "Genres".
*Fixed error in summary retrieval.
*Fixed the help function.  Added calls and settings needed
 to document new features from previous version.
+Added conditional elements to templating language.
+Added option to bind to multiple triggers.
+Split script into a multiple directory/file structure for
 easier maintenance.
+Added themes support.  See default.theme for example.
Post Reply