Pages

Sunday, August 28, 2011

wiki.tcl

# wiki.tcl, v1.6
#  Expand wiki links to URIs.
#  Copyright (c)2007 Kacper Gutowski <mwgamera(a)gmail.com>

#  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, write to the Free Software
#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

#  Expands wiki links in public messages to URIs.
#
#  For example if you type on channel "The best bot - [[eggdrop]]!" bot will
#  reply with "[eggdrop] http://en.wikipedia.org/wiki/eggdrop" if default is
#  Wikipedia and English language. There may be more than one link in a message.
#
#  Following link formats are recognized:
#    1. Double square brackets, e.g. [[link]]
#       Makes a wiki link. Optionally there may be a displayed name after a pipe,
#       e.g. [[Ugly and long link to something|some page]]
#    2. Double braces, e.g. {{template}}
#       Makes a link to template page, i.e. prepends with $wiki_templ
#       if other prefixes (except project and language) are not specified.
#    3. CamelCase links, e.g. WikiLink
#       Makes a wiki link. lowerCamelCase is also supported.
#
#  Before link there may be some colon separated prefixes. Those which
#  are specified in $wiki_pro and $wiki_langs will be interpreted
#  as project and language prefixes and translated to given project URI,
#  e.g. [[q:en:Muzyka]] will (in default configuration) point to Polish
#  Wikiquote page about Music.
#
#  Known issues:
#    * Sometimes eggdrop see lower UTF-8 encoded non-ASCII characters
#      as some upper case Latin, e.g. U+0144 LATIN SMALL LETTER N WITH ACUTE
#      which has UTF-8 representation of 0xC5 0x84 may be seen by eggdrop as
#      U+0044 LATIN CAPITAL LETTER D which may lead to misinterpreting a word
#      as a CamelCase. This probably may occur with other multi-byte encodings.

#  Thanks to Nathan (http://nathanr.ca/) for his useful feedback
#  and Where for CTCP ACTION handling


#### CONFIGURATION ####
# Default language for this bot
# You may change this to any language listed
# in $wiki_langs (see at the end of file for the list)
set wiki_lang "en"

# Default wiki for this bot
# You may change this to any project listed
# in $wiki_pro (see at the end of file for the list)
set wiki_wiki "w"

# Use CamelCase? (set to 0 if bothered with the issue above)
set wiki_camelcase 1

#### DATA PROTOTYPES ####
# Example data is stored at the end of file and you may want to change it.
# List of languages (must be lower case)
set wiki_langs {}
# List of project names (must be lower case)
set wiki_pro {}
# List of project URI templates
set wiki_prob {}
# Template prefix used for {{template}} links
set wiki_templ "Template:"

# Channel specific defaults
# Example data is stored at the end of file and YOU SHOULD CHANGE IT.
# List of channels
set wiki_chan {}
# List of channel languages
set wiki_chan_lang {}
# List of channel projects
set wiki_chan_wiki {}

#### VERSION ####
set env(wiki_version) "1.6"

#### CODE ####
bind pubm - * run_wiki
bind ctcp - * run_wiki_ctcp
bind pub - "!wiki" run_wiki_cmd

# CTCP handling by Where
proc run_wiki_ctcp {nick host hand dest key rest} {
    if {[regexp "^#" $dest]} {
        run_wiki $nick $host $hand $dest $rest
    }
}

# !wiki public command handling
proc run_wiki_cmd {nick uhost hand chan text} {
    putserv "PRIVMSG $chan :\[\2$text\2\] [wikiize $text \[ $chan]"
}

# Message handler
proc run_wiki {nick uhost hand chan arg} {
    global wiki_camelcase
    # select links from text
    set links [concat \
        [regexp -all -inline {\[\[([^\[\]]+)\]\]} $arg] \
        [regexp -all -inline {\{\{([^\\\{\\\}]+)\}\}} $arg] \
    ]
    if {$wiki_camelcase} {
        set links [concat $links \
        [regexp -all -inline {(?:^|[^0-9A-\}])([0-9A-Za-z\.:]*(?:[A-Z][a-z\.]*){2,}[a-z])(?![0-9A-\}])} $arg]]
    }
    # check
    if {[llength $links] < 2 || [expr [llength $links] % 2] != 0} { return }
    set i 1
    while {$i < [llength $links]} {
        set link [lindex $links $i]
        # link type
        set type [string index [lindex $links [expr $i -1]] 0]
        # named links
        if {[string first "|" $link] > 0} {
            set p [split $link "|"]
            set link [lindex $p 0]
            set name [lindex $p 1]
        } else { set name $link }
        # send results
        putserv "PRIVMSG $chan :\[\2$name\2\] [wikiize $link $type $chan]"
        set i [expr $i + 2]
    }
}

# Get URI of given wiki link
proc wikiize { link type chan } {
    global wiki_lang wiki_wiki wiki_langs wiki_pro wiki_prob wiki_templ
    global wiki_chan wiki_chan_wiki wiki_chan_lang
    # load defaults
    set project $wiki_wiki
    set lang $wiki_lang
    if {[lsearch $wiki_chan $chan] >= 0} {
        set project [lindex $wiki_chan_wiki [lsearch $wiki_chan $chan]]
        set lang [lindex $wiki_chan_lang [lsearch $wiki_chan $chan]]
    }
    # check project & language prefixes
    set px [split $link ":"]
    set link {}
    if {[string length $px] > 1} {
        set pi 0
        while {$pi<[llength $px]-1} {
            set prefix [string tolower [lindex $px $pi]]
            if {[lsearch $wiki_pro $prefix] >= 0} {
                # project found
                set project $prefix
            } elseif {[lsearch $wiki_langs $prefix] >= 0} {
                # language found
                set lang $prefix
            } else {
                # not a prefix
                lappend link [lindex $px $pi]
            }
            set pi [expr $pi +1]
        }
    }
    lappend link [lindex $px end]
    # link type
    if {$type == "\{"} {
        # template
        if {[llength $link] > 1} {
            # have other prefixes - ignore template
            set link [join $link ":"]
        } else {
            # add template prefix
            set link [join [list $wiki_templ [join $link ":"]] ""]
        }
    } else {
        # other
        set link [join $link ":"]
    }
    # URL-encoding
    regsub -all " " $link "_" link
    regsub -all "!" $link "%21" link
    regsub -all "\"" $link "%22" link
    regsub -all "&"  $link "%26" link
    regsub -all {\+} $link "%2B" link
    regsub -all {\\} $link "%5C" link
    regsub -all {\(} $link "%28" link
    regsub -all {\)} $link "%29" link
    # make URI
    set uri [lindex $wiki_prob [lsearch $wiki_pro $project]]
    regsub "LNG" $uri $lang uri
    regsub "PG" $uri $link uri
    return $uri
}

#### DATA ####
# = Languages =
lappend wiki_langs af als ar ast id ms zh-min-nan jv be bg bs ca cs cy da de et el
lappend wiki_langs en es eo eu fa fo fr fy ga gd gl ko hy hi hr io ia os is it
lappend wiki_langs he kn ka csb ku la lv lb lt li hu mk mr mn nl ja no nn nds
lappend wiki_langs pt pl ro ru sq scn simple sk sl sr sh fi sv tl ta tt te th vi
lappend wiki_langs tr uk wa zh


# = Wiki Projects =
#  LNG is replaced with language code and PG with page name

# Wikipedia (w)
lappend wiki_pro "w"
lappend wiki_prob "http://LNG.wikipedia.org/wiki/PG"
# Meta (m, meta)
lappend wiki_pro "m"
lappend wiki_prob "http://meta.wikimedia.org/wiki/PG"
lappend wiki_pro "meta"
lappend wiki_prob "http://meta.wikimedia.org/wiki/PG"
# Commons (commons)
lappend wiki_pro "commons"
lappend wiki_prob "http://commons.wikimedia.org/wiki/PG"
# Wikitionary (wikit, wiktionary)
lappend wiki_pro "wikit"
lappend wiki_prob "http://LNG.wiktionary.org/wiki/PG"
lappend wiki_pro "wiktionary"
lappend wiki_prob "http://LNG.wiktionary.org/wiki/PG"
# Wikisource (s, source)
lappend wiki_pro "s"
lappend wiki_prob "http://LNG.wikisource.org/wiki/PG"
lappend wiki_pro "source"
lappend wiki_prob "http://LNG.wikisource.org/wiki/PG"
# Wikiquote (q, quote)
lappend wiki_pro "q"
lappend wiki_prob "http://LNG.wikiquote.org/wiki/PG"
lappend wiki_pro "quote"
lappend wiki_prob "http://LNG.wikiquote.org/wiki/PG"
# Wikibooks (b, books)
lappend wiki_pro "b"
lappend wiki_prob "http://LNG.wikibooks.org/wiki/PG"
lappend wiki_pro "books"
lappend wiki_prob "http://LNG.wikibooks.org/wiki/PG"
# Wikinews (n, news)
lappend wiki_pro "n"
lappend wiki_prob "http://LNG.wikinews.org/wiki/PG"
lappend wiki_pro "news"
lappend wiki_prob "http://LNG.wikinews.org/wiki/PG"
# Wikispecies (wikispecies)
lappend wiki_pro "wikispecies"
lappend wiki_prob "http:/species.wikimedia.org/wiki/PG"

# WikiWikiWeb
lappend wiki_pro "wiki"
lappend wiki_prob "http://c2.com/cgi/wiki?PG"
# MeatBall
lappend wiki_pro "meatball"
lappend wiki_prob "http://www.usemod.com/cgi-bin/mb.pl?PG"
lappend wiki_pro "mb"
lappend wiki_prob "http://www.usemod.com/cgi-bin/mb.pl?PG"
# AboutUs.org
lappend wiki_pro "aboutus"
lappend wiki_prob "http://www.aboutus.org/PG"


# = Channel specific defaults =
# Example channel entry: on #dict default is english wikitionary
lappend wiki_chan "#dict"
lappend wiki_chan_lang "en"
lappend wiki_chan_wiki "wikit"


#### SETUP DONE ####
putlog "wiki v$env(wiki_version)... loaded"

No comments:

Post a Comment