| View previous topic :: View next topic |
| Author |
Message |
koom Voice
Joined: 30 Jul 2005 Posts: 22
|
Posted: Sat Jul 30, 2005 9:43 pm Post subject: RSSNews.tcl - by perpleXa --- Help! |
|
|
Hey all,
I've got an rss bot set up in my channel, but for the sake of my life i cant get the bot to notice the people who triggered (it keeps noticing the channel, not the people)
| Code: |
## $Id: rssnews.tcl,v 4.5.0251 2005/01/04 9:12PM perpleXa Exp $
## -------------------------------------------------------------
## ___ ___ ___
## /\ \ /\ \ /\ \
## /::\ \ /::\ \ /::\ \
## /:/\:\ \ /:/\ \ \ /:/\ \ \
## /::\~\:\ \ _\:\~\ \ \ _\:\~\ \ \
## /:/\:\ \:\__\ /\ \:\ \ \__\ /\ \:\ \ \__\
## \/_|::\/:/ / \:\ \:\ \/__/ \:\ \:\ \/__/
## |:|::/ / \:\ \:\__\ \:\ \:\__\
## |:|\/__/ \:\/:/ / \:\/:/ /
## |:| | \::/ / \::/ /
## \|__| \/__/ \/__/ feed parser
##
## http://perpleXa.net | http://dev.perpleXa.net
## #perpleXa on QuakeNet
## (C) 2004
##
## This script is approved to parse all valid RSS feeds.
## If You discover any issues regarding installing or running
## this script so feel free to contact me on QuakeNet.
##
## Enjoy.
##
##
## FAQ:
##
## Q. What are these weird characters in the layout?
## A. You can use <upfirstchar text>, <id>, <publisher>, <news>, <link>,
## as well as control codes, to change the design to something you'd like
## Available colors and control codes are:
## \002 bold
## \003 [00-15] colors
## \017 reset control codes
## \026 reverse
## \037 underline
##
## Q. How do I control this script?
## A. There isn't much to say, just type $news <feed> in a channel or /msg <bot> news <feed>
## All the other stuff works automatically. ie. When you set your feed like "set feed(ESReality) { ... }"
## you have to type $news ESReality or /msg <bot> news ESReality to receive news from that feed.
##
## Q. How do I setup my own feeds?
## A. Look at the examples below, you should find all neccessary information in the first one.
##
## Q. Where can I find more feeds?
## A. Try out http://www.feedroom.com and http://www.syndic8.com/
##
## Q. I've discovered a bug, what should I do?
## A. Write an email, use the contact field on my website or contact me on #perpleXa (QuakeNet)
##
## -------------------------------------------------------------
## Don't touch this line!
array unset feed
##
## -------------------------------------------------------------
## ---- Setup --------------------------------------------------
set feed() {
URL= /* The location of the news, in format http://domain.com:port/file.xml (port value is optional). */
DATABASE=scripts/rss/.chat /* The file where the news are saved. */
CHANNELS=#chat /* On which channels is the feed activated? Set to ALL for all channels. */
POSTNEWS=1 /* Post news if there are new ones? */
POSTLIMIT=5 /* max. posted news */
PUBLIMIT=5 /* How many news are posted on pub triggers? */
MSGLIMIT=10 /* How many news are posted on msg triggers? */
/* Thats the design used for automated output. */
POSTLAYOUT=\00300,14\[\00309\002!\002\00300\] \002www.bt-chat.com \[\00309\002!\002\00300\] <news> \[\00309\002!\002\00300\] <link> \[\00309\002!\002\00300\]\003^M
/* And this one is for use on trigger events. */
TRIGLAYOUT=\00300,14\[\00309\002!\002\00300\] \002www.bt-chat.com \[\00309\002!\002\00300\] <news> \[\00309\002!\002\00300\] <link> \[\00309\002!\002\00300\]\003
}
## ---- End of Setup -------------------------------------------
## -------------------------------------------------------------
if {[package vcompare [info tclversion] 8.4] < 0} {
putlog "You don't have TCL 8.4, you have to upgrade to version 8.4 or higher to use [file tail [info script]]."
return;
}
package require http
namespace eval rss {
variable protect 60
variable timeout 20
variable pubbind {!chat}
variable msgbind {news}
variable v_major 4
variable v_minor 5
variable v_build 0251
variable version $v_major.$v_minor.$v_build
variable client "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7) Gecko/20040803 Firefox/0.9.3"
bind PUB -|- $pubbind [namespace current]::public
bind MSG -|- $msgbind [namespace current]::private
bind TIME -|- {?0 * * * *} [namespace current]::check
namespace export public private check
}
proc rss::check {args} {
global feed
variable client
variable timeout
putquick "PING :[clock seconds]" -next
foreach id [array names feed] {
set url "0"
set database "0"
set channels "0"
set postnews "1"
set postlimit "3"
set publimit "3"
set msglimit "10"
set postlayout {\00314(\00307<publisher>\00314)\00307 <news> \00314<\00307<link>\00314>\003}
foreach line [split $feed($id) \n] {
regsub -all -- {/\*.*?\*/} $line {} line
regexp -nocase -- {^\s*URL=(.+?)\s*$} $line tmp url
regexp -nocase -- {^\s*DATABASE=(.+?)\s*$} $line tmp database
regexp -nocase -- {^\s*CHANNELS=(.+?)\s*$} $line tmp channels
regexp -nocase -- {^\s*POSTNEWS=(.+?)\s*$} $line tmp postnews
regexp -nocase -- {^\s*POSTLIMIT=(.+?)\s*$} $line tmp postlimit
regexp -nocase -- {^\s*PUBLIMIT=(.+?)\s*$} $line tmp publimit
regexp -nocase -- {^\s*MSGLIMIT=(.+?)\s*$} $line tmp msglimit
regexp -nocase -- {^\s*POSTLAYOUT=(.+?)\s*$} $line tmp postlayout
}
if {($url == 0) || ($database == 0) || ($channels == 0)} {
putlog "RSS: Warning: Couldn't load configuration for the \[$id\] feed."
continue
}
if {$postnews == 0} {
continue
}
if {![file isdirectory [file dirname $database]]} {
file mkdir [file dirname $database]
}
set count 0
set data {}
http::config -useragent $client
catch {http::geturl $url -command "[namespace current]::check:data {$database} {$channels} {$postlimit} {$postlayout}" -timeout [expr $timeout * 1000]}
}
}
proc rss::check:data {database channels postlimit postlayout token} {
upvar 0 $token state
if {![string equal -nocase $state(status) "ok"]} {
return 0
}
set latestnews "iddqd"
if {[file exists $database]} {
set temp [open $database r+]
set latestnews [gets $temp]
if {[string length $latestnews] <= 1} {
set latestnews "iddqd"
}
close $temp
}
set data [http::data $token]
http::cleanup $token
set publisher [publisher $data]
set data [parse $data]
set temp [open $database w+]
set postlayout [join $postlayout { }]
foreach {item} $data {
regsub -all -- {<id>} $postlayout [lindex $item 0] output
regsub -all -- {<publisher>} $output $publisher output
regsub -all -- {<link>} $output [lindex $item 1] output
regsub -all -- {<news>} $output [lindex $item 2] output
regsub -all -- {<upfirstchar\s(.*?)>} [clean $output] {[upfirstchar "\1"]} output
puts $temp [decode [subst $output]]
}
close $temp
set count 0
set temp [open $database r+]
while {![eof $temp]} {
gets $temp headline
if {([string equal -nocase $latestnews $headline]) || ([string equal -nocase $latestnews "iddqd"]) || ($count == $postlimit)} {
break
}
incr count
notice $channels $headline
}
close $temp
}
proc rss::news {target id type} {
global feed
variable client
variable timeout
if {$type == 2} {
set msgtype NOTICE
} else {
set msgtype NOTICE
}
set url "0"
set publimit "5"
set msglimit "10"
set triglayout "\00314\[\00307<id>\00314\]\00307 <news> \00314<\00307<link>\00314>\003"
foreach item [split $feed($id) \n] {
regsub -all -- {/\*.*?\*/} $item {} item
regexp -nocase -- {^\s*URL=(.+?)\s*$} $item tmp url
regexp -nocase -- {^\s*PUBLIMIT=(.+?)\s*$} $item tmp publimit
regexp -nocase -- {^\s*MSGLIMIT=(.+?)\s*$} $item tmp msglimit
regexp -nocase -- {^\s*TRIGLAYOUT=(.+?)\s*$} $item tmp triglayout
}
if {($url == 0)} {
putquick "$msgtype $target :Warning: Couldn't load configuration for the \[$id\] feed."
return 0
}
if {$type == 1} {
set limit $msglimit
} elseif {$type == 2} {
set limit $publimit
} else {
return 0
}
http::config -useragent $client
catch {http::geturl $url -timeout [expr $timeout * 1000]} token
if {[regexp -nocase -- {^couldn\'t\sopen\ssocket:\s+?(.*)$} $token tmp state(status)]} {
putquick "$msgtype $target :Warning: Couldn't connect to the \[$id\] feed ($state(status))."
return 0
}
upvar 0 $token state
if {![string equal -nocase $state(status) "ok"]} {
putquick "$msgtype $target :Warning: Couldn't connect to the \[$id\] feed (connection $state(status))."
return 0
}
set data [http::data $token]
http::cleanup $token
set publisher [publisher $data]
set data [parse $data]
set count 0
set triglayout [join $triglayout { }]
foreach {item} $data {
incr count
regsub -all -- {<id>} $triglayout [lindex $item 0] output
regsub -all -- {<publisher>} $output $publisher output
regsub -all -- {<link>} $output [lindex $item 1] output
regsub -all -- {<news>} $output [lindex $item 2] output
regsub -all -- {<upfirstchar\s(.*?)>} [clean $output] {[upfirstchar "\1"]} output
set output [decode [subst $output]]
if {$type == 2} {
if {[regexp -- {c} [getchanmode $target]]} {
set output [stripcodes c $output]
}
}
puthelp "$msgtype $target :$output"
if {($count == $limit)} {
break
}
}
}
proc rss::publisher {content} {
set publisher {n/a}
regsub -all -- {\n+|\s+|\t+} $content { } content
regsub -all -- {([\\&])} $content {\\\1} content
regexp -nocase -- {<title>(.+?)</title>} $content tmp publisher
return $publisher
}
proc rss::parse {content} {
regsub -all -- {\n+|\s+|\t+} $content { } content
regsub -all -- {([\\&])} $content {\\\1} content
set item 0
set news ""
while {[regexp -nocase -- {<item(\s[^>]*?)?>(.+?)</item>} $content -> & value]} {
incr item
set title {n/a}
regexp -nocase -- {<title>(.+?)</title>} $value -> title
regexp -nocase -- {\<\!\[CDATA\[(.*?)\]\]\>} $title -> title
set link {n/a}
regexp -nocase -- {<link>(.+?)</link>} $value -> link
regexp -nocase -- {\<\!\[CDATA\[(.*?)\]\]\>} $link -> link
regsub -nocase -- {<item.*?>.+?</item>} $content {} content
lappend news "$item {$link} {$title}"
}
return [lsort -integer -unique -index 0 $news]
}
proc rss::decode {content} {
if {![regexp -- & $content]} {
return $content
}
set escapes {
\x20 " \x22 & \x26 ' \x27 – \x2D < \x3C > \x3E ˜ \x7E € \x80 ¡ \xA1
¢ \xA2 £ \xA3 ¤ \xA4 ¥ \xA5 ¦ \xA6 § \xA7 ¨ \xA8 © \xA9 ª \xAA « \xAB
¬ \xAC ­ \xAD ® \xAE &hibar; \xAF ° \xB0 ± \xB1 ² \xB2 ³ \xB3 ´ \xB4 µ \xB5
¶ \xB6 · \xB7 ¸ \xB8 ¹ \xB9 º \xBA » \xBB ¼ \xBC ½ \xBD ¾ \xBE ¿ \xBF
À \xC0 Á \xC1 Â \xC2 Ã \xC3 Ä \xC4 Å \xC5 Æ \xC6 Ç \xC7 È \xC8 É \xC9
Ê \xCA Ë \xCB Ì \xCC Í \xCD Î \xCE Ï \xCF Ð \xD0 Ñ \xD1 Ò \xD2 Ó \xD3
Ô \xD4 Õ \xD5 Ö \xD6 × \xD7 Ø \xD8 Ù \xD9 Ú \xDA Û \xDB Ü \xDC Ý \xDD
Þ \xDE ß \xDF à \xE0 á \xE1 â \xE2 ã \xE3 ä \xE4 å \xE5 æ \xE6 ç \xE7
è \xE8 é \xE9 ê \xEA ë \xEB ì \xEC í \xED î \xEE ï \xEF ð \xF0 ñ \xF1
ò \xF2 ó \xF3 ô \xF4 õ \xF5 ö \xF6 ÷ \xF7 ø \xF8 ù \xF9 ú \xFA û \xFB
ü \xFC ý \xFD þ \xFE ÿ \xFF
}
set content [string map $escapes $content]
regsub -all -- {&[a-zA-Z]+?;} [clean $content] {?} content
regsub -all -- {&#(\d{1,3});} $content {[format %c [scan \1 %d]]} content
return [subst $content]
}
proc rss::private {nickname hostname handle arguments} {
global feed
variable spam
variable protect
set arguments [clean $arguments]
set spewfeed [lindex $arguments 0]
if {![validfeed $spewfeed 1]} {
putquick "NOTICE $nickname :Please supply a valid feed: [join [lsort -dictionary [array names feed]] ",\x20"]"
return 0
}
set spewfeed [validfeed $spewfeed 2]
if {([info exists spam(flood,$spewfeed,$hostname)])} {
set s [expr [clock seconds] - $spam(flood,$spewfeed,$hostname)]
if {$s < $protect} {
putquick "NOTICE $nickname :Sorry - This trigger has recently been used. It will be unlocked in [expr $protect - $s] seconds."
return 0
}
}
set spam(flood,$spewfeed,$hostname) [clock seconds]
news $nickname $spewfeed 1
}
proc rss::public {nickname hostname handle channel arguments} {
global feed
variable spam
variable protect
set arguments [clean $arguments]
set spewfeed [lindex $arguments 0]
if {![validfeed $spewfeed 1]} {
putquick "PRIVMSG $channel :Please supply a valid feed: [join [lsort -dictionary -unique [array names feed]] ",\x20"]"
return 0
}
set spewfeed [validfeed $spewfeed 2]
if {([info exists spam(flood,$spewfeed,$channel)]) && (![isop $nickname $channel])} {
set s [expr [clock seconds] - $spam(flood,$spewfeed,$channel)]
if {$s < $protect} {
putquick "PRIVMSG $channel :Sorry - This trigger has recently been used. It will be unlocked in [expr $protect - $s] seconds."
return 0
}
}
set spam(flood,$spewfeed,$channel) [clock seconds]
set channels 0
foreach item [split $feed($spewfeed) \n] {
regsub -all -- {/\*.*\*/} $item {} item
regexp -nocase -- {^\s*CHANNELS=(.+?)\s*$} $item tmp channels
}
if {([lsearch -exact [string tolower $channels] [string tolower $channel]] == -1) && (![string equal -nocase $channels "ALL"])} {
putquick "PRIVMSG $channel :The \[$spewfeed\] feed is not available on this channel. ($channels)"
return 0
}
news $channel $spewfeed 2
}
proc rss::msg {channels headline} {
if {[string equal -nocase $channels "ALL"]} {
foreach channel [channels] {
if {[regexp -- {c} [getchanmode $channel]] && [regexp -- {\003} $headline]} {
lappend nocolors $channel
} else {
lappend colors $channel
}
}
} else {
foreach channel [channels] {
if {[lsearch -exact [string tolower $channels] [string tolower $channel]] >= 0} {
if {[regexp -- {c} [getchanmode $channel]] && [regexp -- {\003} $headline]} {
lappend nocolors $channel
} else {
lappend colors $channel
}
}
}
}
if {[info exists nocolors]} {
putquick "PRIVMSG [join $nocolors {,}] :[stripcodes c $headline]"
}
if {[info exists colors]} {
putquick "PRIVMSG [join $colors {,}] :$headline"
}
}
proc rss::validfeed {keyword type} {
global feed
foreach id [array names feed] {
if {[string equal -nocase $id $keyword]} {
switch -exact -- $type {
{1} {
return 1
}
{2} {
return $id
}
}
}
}
return 0
}
proc rss::upfirstchar {content} {
regsub -all -- {((^|\s)([a-z]))} [clean $content] {[string toupper "\1"]} content
return [subst $content]
}
proc rss::clean {string} {
regsub -all -- {([\(\)\[\]\{\}\$\"\\])} $string {\\\1} string
return $string
}
putlog "Script loaded: RSS feed parser $rss::version (C) 2004 perpleXa."
|
Anyway,i hope someone can help,
Koom[/code] |
|
| Back to top |
|
 |
demond Revered One

Joined: 12 Jun 2004 Posts: 3073 Location: San Francisco, CA
|
Posted: Sat Jul 30, 2005 10:07 pm Post subject: |
|
|
| substitute $channel with $nickname at [news] invocation in [rss::public] |
|
| Back to top |
|
 |
koom Voice
Joined: 30 Jul 2005 Posts: 22
|
Posted: Sat Jul 30, 2005 11:36 pm Post subject: |
|
|
::13:04:: -BTC-Bot- [21:34] Tcl error [::rss::public]: invalid channel: [BTC]Koom
almost there, thats my nickname there, but it doesnt wanna send.. |
|
| Back to top |
|
 |
DragnLord Owner

Joined: 24 Jan 2004 Posts: 711 Location: C'ville, Virginia, USA
|
Posted: Sun Jul 31, 2005 12:56 am Post subject: unless I'm too tired to read the code correctly (possible).. |
|
|
When the script is triggered through the pub bind (triggered in message to the channel) the script gives the output to the channel, when triggered by private message to the bot (query, not dcc) the bot responds with only to that person.
This is what demond is saying to do (rephrased):
The line of code to change in rss::public
| Code: | | news $channel $spewfeed 2 |
To:
| Code: | | news $nickname $spewfeed 2 |
|
|
| Back to top |
|
 |
koom Voice
Joined: 30 Jul 2005 Posts: 22
|
Posted: Sun Jul 31, 2005 1:18 am Post subject: |
|
|
Yeah i under stand DragnLord, and i changed the script accordingly, but like i said, it still errors
"::13:04:: -BTC-Bot- [21:34] Tcl error [::rss::public]: invalid channel: [BTC]Koom"
I just need to change that to tell it that its actually a user and not a channel  |
|
| Back to top |
|
 |
DragnLord Owner

Joined: 24 Jan 2004 Posts: 711 Location: C'ville, Virginia, USA
|
Posted: Sun Jul 31, 2005 2:40 am Post subject: |
|
|
yep, I'm tired...
try:
news $nickname $spewfeed 1
(the '2' makes the script check for channel modes, which a nick won't have) |
|
| Back to top |
|
 |
koom Voice
Joined: 30 Jul 2005 Posts: 22
|
Posted: Sun Jul 31, 2005 3:04 am Post subject: |
|
|
Thanks DragnLord, i just tried that, but i encounted another error..
::16:32:: -BTC|Bot- [01:02] Tcl error [::rss::public]: can't read "feed(1)": no such element in array
So i'm not too sure what to do now  |
|
| Back to top |
|
 |
DragnLord Owner

Joined: 24 Jan 2004 Posts: 711 Location: C'ville, Virginia, USA
|
Posted: Sun Jul 31, 2005 3:14 am Post subject: |
|
|
| copy&paste just the rss::public and rss::news procs |
|
| Back to top |
|
 |
koom Voice
Joined: 30 Jul 2005 Posts: 22
|
Posted: Sun Jul 31, 2005 3:22 am Post subject: |
|
|
| Code: |
proc rss::public {nickname hostname handle channel arguments} {
global feed
variable spam
variable protect
set arguments [clean $arguments]
set spewfeed [lindex $arguments 0]
if {![validfeed $spewfeed 1]} {
putquick "PRIVMSG $channel :Please supply a valid feed: [join [lsort -dictionary -unique [array names feed]] ",\x20"]"
return 0
}
set spewfeed [validfeed $spewfeed 1]
if {([info exists spam(flood,$spewfeed,$channel)]) && (![isop $nickname $channel])} {
set s [expr [clock seconds] - $spam(flood,$spewfeed,$channel)]
if {$s < $protect} {
putquick "PRIVMSG $channel :Sorry - This trigger has recently been used. It will be unlocked in [expr $protect - $s] seconds."
return 0
}
}
set spam(flood,$spewfeed,$channel) [clock seconds]
set channels 0
foreach item [split $feed($spewfeed) \n] {
regsub -all -- {/\*.*\*/} $item {} item
regexp -nocase -- {^\s*CHANNELS=(.+?)\s*$} $item tmp channels
}
if {([lsearch -exact [string tolower $channels] [string tolower $channel]] == -1) && (![string equal -nocase $channels "ALL"])} {
putquick "PRIVMSG $channel :The \[$spewfeed\] feed is not available on this channel. ($channels)"
return 0
}
news $nickname $spewfeed 1
}
|
| Code: |
proc rss::news {target id type} {
global feed
variable client
variable timeout
if {$type == 2} {
set msgtype NOTICE
} else {
set msgtype NOTICE
|
Thanks Alot  |
|
| Back to top |
|
 |
DragnLord Owner

Joined: 24 Jan 2004 Posts: 711 Location: C'ville, Virginia, USA
|
Posted: Sun Jul 31, 2005 3:32 am Post subject: |
|
|
you missed at least half of rss::news, I don't feel so bad now
we'll try an easier fix for this:
| Code: | bind PUB -|- $pubbind [namespace current]::public
bind MSG -|- $msgbind [namespace current]::private |
to:
| Code: | bind PUB -|- $pubbind [namespace current]::private
bind MSG -|- $msgbind [namespace current]::private |
See how that works for you. |
|
| Back to top |
|
 |
koom Voice
Joined: 30 Jul 2005 Posts: 22
|
Posted: Sun Jul 31, 2005 3:36 am Post subject: |
|
|
| DragnLord wrote: | you missed at least half of rss::news, I don't feel so bad now
|
Hehe, sorry about that, i'm not in my right state of mind atm..
Anyway, i tried what you suggested, but i received yet another error
"::17:05:: -BTC|Bot- [01:35] Tcl error [::rss::private]: wrong # args: should be "::rss::private nickname hostname handle arguments""
Thanks  |
|
| Back to top |
|
 |
DragnLord Owner

Joined: 24 Jan 2004 Posts: 711 Location: C'ville, Virginia, USA
|
Posted: Sun Jul 31, 2005 3:45 am Post subject: |
|
|
since I don't know what you are sending to the bot, I can't help much
need to know what you are inputting to get the error
maybe a little rest will help  |
|
| Back to top |
|
 |
koom Voice
Joined: 30 Jul 2005 Posts: 22
|
Posted: Sun Jul 31, 2005 3:47 am Post subject: |
|
|
ah yes, i should've mentioned that too
that error just happens when i try the trigger (in this case !chat) |
|
| Back to top |
|
 |
DragnLord Owner

Joined: 24 Jan 2004 Posts: 711 Location: C'ville, Virginia, USA
|
Posted: Sun Jul 31, 2005 3:53 am Post subject: |
|
|
recheck your configurations
if they are the same as what you have posted, make sure you set a source URL (and the other feed settings) |
|
| Back to top |
|
 |
koom Voice
Joined: 30 Jul 2005 Posts: 22
|
Posted: Sun Jul 31, 2005 4:09 am Post subject: |
|
|
Thanks for your help, i tinkered around with this
| Code: |
bind PUB -|- $pubbind [namespace current]::private
bind MSG -|- $msgbind [namespace current]::private
|
and changed it back to default
| Code: |
bind PUB -|- $pubbind [namespace current]::public
bind MSG -|- $msgbind [namespace current]::private
|
Working great now!  |
|
| Back to top |
|
 |
|