Announce news from a website on IRC

# newsannouncer.tcl
#
# Copyright (c) 2003 Jochen "Y0Gi" Kupperschmidt <http://homework.nwsnet.de/>
# Version: 01-Oct-2003
# Released under the terms of the MIT License.
#
# Periodically check a webpage for news and announce them
# on an IRC channel.
#
# Compares the first line of the given URL (which should
# contain the latest news headline from your website as
# plain text; in most cases you will want read that line
# dynamically from your website's database) with the
# locally stored headline and announces it to the
# specified IRC channels, if newer.
#
# Commands provided:
#   !latestnews  - print latest (cached!) news
#   !news        - print command list
#   !news status - state if timed check is active
#   !news start  - continue timed check
#   !news stop   - halt timed check
#   !news update - force immediate check
#   !news reset  - clear data from last check

# configuration
set na(file)     "newsannouncer.dat"
set na(url)      "http://yourserver.example.com/latestnews.php"
set na(channels) "#channel1 #channel2 #channel3"
set na(prefix)   "New headline:"
set na(active)   0


# User command. Display latest (cached!) news.
bind pub - "!latestnews" na:pub:latestnews

# Admin command. Set flags as you prefer.
bind pub - "!news" na:pub:checknews

# Check every ten minutes.
bind time - "?0 * * * *" na:time:checknews


package require http

proc na:pub:latestnews {nick host hand chan text} {
    global na
    if {![file exists $na(file)]} {
        set msg "No cache file found."
    } else {
        set fh [open $na(file) r]
        gets $fh msg
        close $fh
    }
    puthelp "PRIVMSG $chan :$msg"
    return 0
}

proc na:pub:checknews {nick nhost hand chan text} {
    global na
    if {$text == "status"} {
        if {$na(active) == 1} {
            set msg "News check is currently active."
        } else {
            set msg "News check is currently not active."
        }
    } elseif {$text == "start"} {
        set na(active) 1
        set msg "News check activated."
    } elseif {$text == "stop"} {
        set na(active) 0
        set msg "News check deactivated."
    } elseif {$text == "update"} {
        na:checknews
        set msg "News check performed."
    } elseif {$text == "reset"} {
        catch {exec rm $na(file)}
        set msg "News check resetted."
    } else {
        set msg "Usage: !news \{start|stop|status|update|reset\}"
    }
    puthelp "PRIVMSG $chan :$msg"
    return 0
}

proc na:time:checknews {min hour day mon year} {
    global na
    if {$na(active) == 1} {
        na:checknews
    }
    return 0
}

proc na:checknews {} {
    global na

    # Read local data
    if {![file exists $na(file)]} {
        catch {exec touch $na(file)}
    }
    set fh [open $na(file) r]
    gets $fh local
    close $fh

    # Read online data
    set data [http::data [http::geturl $na(url)]]
    set online [lindex [split $data \n] 0]

    # Check for a different news headline
    if {$online != $local} {
        # store new headline
        set fh [open $na(file) w]
        puts $fh $online
        close $fh

        # Announce to given channels
        foreach channel [split $na(channels)] {
            puthelp "PRIVMSG $channel :$na(prefix) $online"
        }
    }
    return 0
}

putlog "newsannouncer.tcl loaded."