Difference between revisions of "User:Katharine Berry/Scripts/Pandorabot"

From The SchomEmunity Wiki
Jump to: navigation, search
(Script: Updated to 2.2)
m (Script: Fixed the license.)
Line 10: Line 10:
 
<pre><nowiki>
 
<pre><nowiki>
 
// Pandorabots v2.2.
 
// Pandorabots v2.2.
// Copyright (c) 2007, Katharine Berry
+
// Copyright (c) 2007, Katharine Schomer
 
// All rights reserved.
 
// All rights reserved.
 
//
 
//
Line 20: Line 20:
 
//      notice, this list of conditions and the following disclaimer in the
 
//      notice, this list of conditions and the following disclaimer in the
 
//      documentation and/or other materials provided with the distribution.
 
//      documentation and/or other materials provided with the distribution.
//    * Neither the name of Katharine Berry nor the names of any contributors
+
//    * Neither the name of Katharine Schomer nor the names of any contributors
 
//      may be used to endorse or promote products derived from this software
 
//      may be used to endorse or promote products derived from this software
 
//      without specific prior written permission.
 
//      without specific prior written permission.
 
//
 
//
// THIS SOFTWARE IS PROVIDED BY KATHARINE BERRY ``AS IS'' AND ANY
+
// THIS SOFTWARE IS PROVIDED BY KATHARINE SCHOMER ``AS IS'' AND ANY
 
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL KATHARINE BERRY BE LIABLE FOR ANY
+
// DISCLAIMED. IN NO EVENT SHALL KATHARINE SCHOMER BE LIABLE FOR ANY
 
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;

Revision as of 23:45, 1 August 2007

Kathy's userpage | Kathy's talk page | Kathy's Scripts | Kathy's talk page archive | Force Reload


This script is an interface to Pandorabots through SL.

Usage

Just change the BOT_ID constant to your bot's botid, and place the script in an object. Say "Shut up" to make it stop listening. Otherwise it listens to everyone, although each person is in a separate conversation.

Script

// Pandorabots v2.2.
// Copyright (c) 2007, Katharine Schomer
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of Katharine Schomer nor the names of any contributors
//       may be used to endorse or promote products derived from this software
//       without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY KATHARINE SCHOMER ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL KATHARINE SCHOMER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ******************************************************************************

string BOT_ID = "f5d922d97e345aa1"; // The botid of the bot on Pandorabots
integer WIKIPEDIA_ENABLED = TRUE; // Whether it should look certain things up on Wikipedia.
list UNWIKIABLE_PHRASES = ["what is my name?"]; // Things not to ever look up on Wikipedia.
integer SINGLE_OBJECT_MIND = TRUE; // Whether to create session IDs unique to the object.

string BOT_API = "http://www.pandorabots.com/pandora/talk-xml";
string WIKIMEDIA_API = "http://schome.katharineberry.co.uk/bots/wiki.php";
list SPECIAL_CHARS = ["<br>","&quot;","&gt;","&lt;"];
list SPECIAL_REPLACEMENTS = ["\n","\"",">","<"];
//The order here is important.
list WIKIPEDIA_TRIGGERS = [
    "what is ","?",
    "what's ","?",
    "what is a ","?",
    "what's a ","?",
    "who is","?",
    "who's","?"
];
// These don't do anything.
list WIKTIONARY_TRIGGERS = [
    "what does "," mean?",
    "what's "," mean?"
];

string EscapeURL(string str) // Wrapper for the buggy llEscapeURL(), which only returns 255 bytes
{
    string escaped = ""; 
    while(str != "")
    {
        escaped += llEscapeURL(llGetSubString(str,0,82));
        str = llDeleteSubString(str,0,82);
    }
    return escaped;
}

string FixHTML(string str)
{
    integer j = 0;
    integer jl = llGetListLength(SPECIAL_CHARS);
    for(j = 0; j < jl; j += 8)
    {
        list special = llList2List(SPECIAL_CHARS,j,j+7);
        list replacements = llList2List(SPECIAL_REPLACEMENTS,j,j+7);
        list s = llParseStringKeepNulls(str,[],special);
        integer i;
        integer l = llGetListLength(s);
        for(i = 1; i < l; i += 2)
        {
            s = llListReplaceList(s, [llList2String(replacements,llListFindList(special,[llList2String(s,i)]))],i,i);
        }
        str = (string)s;
    }
    return str;
}

string gBotID = NULL_KEY;

default
{
    state_entry()
    {
        if(SINGLE_OBJECT_MIND)
        {
            gBotID = "";
        }
        else
        {
            gBotID = llDumpList2String(llParseString2List(llGetKey(),["-"],[]),"");
        }
        llListen(0,"",NULL_KEY,"");
    }
    
    on_rez(integer param)
    {
        if(SINGLE_OBJECT_MIND)
        {
            gBotID = "";
        }
        else
        {
            gBotID = llDumpList2String(llParseString2List(llGetKey(),["-"],[]),"");
        }
    }

    listen(integer channel, string name, key id, string message)
    {
        string lmessage = llToLower(message);
        if(lmessage == "shut up" || lmessage == "shut up." || lmessage == "shut up!")
        {
            state off;
        }
        if(llGetSubString(message,0,2) == "/me")
        {
            message = name+llGetSubString(message,3,-1);
        }
        if(WIKIPEDIA_ENABLED)
        {
            if(!~llListFindList(UNWIKIABLE_PHRASES,[lmessage]))
            {
                integer len = llGetListLength(WIKIPEDIA_TRIGGERS);
                while(len--)
                {
                    string trigger = llList2String(WIKIPEDIA_TRIGGERS,--len); // Warning: clever code
                    if(!llSubStringIndex(lmessage,trigger)) // Checking if it's zero - ! is faster though.
                    {
                        string ending = llList2String(WIKIPEDIA_TRIGGERS,len+1);
                        integer endinglen = llStringLength(ending);
                        if(llGetSubString(lmessage,-endinglen,-1) == ending)
                        {
                            message = llGetSubString(message,llStringLength(trigger),-endinglen - 1);
                            jump wikipedia; // Yay ugliness.
                        }
                    }
                }
            }
        }
        string request = "botid="+BOT_ID+"&input="+EscapeURL(message)+"&custid="+llDumpList2String(llParseString2List(id,["-"],[]),"")+gBotID;
        llHTTPRequest(BOT_API,[HTTP_METHOD,"POST",HTTP_MIMETYPE,"application/x-www-form-urlencoded"],request);
        return;
        @wikipedia;
        llHTTPRequest(WIKIMEDIA_API+"?site=wikipedia&query="+EscapeURL(message),[],"");
        return;
    }
    
    http_response(key id, integer status, list mdata, string body)
    {
        if(status >= 200 && status < 300)
        {
            integer pos = llSubStringIndex(body,"<message>");
            integer endpos = 0;
            if(!~pos)
            {
                pos = llSubStringIndex(body,"<that>") + 6;
                endpos = llSubStringIndex(body,"</that>") - 1;
                llSay(0,FixHTML(llGetSubString(body,pos,endpos)));
            }
            else
            {
                endpos = llSubStringIndex(body,"</message>");
                llSay(0,FixHTML(llGetSubString(body,pos,endpos)));
            }
        }
        else
        {
            llSay(0,"HTTP error #"+(string)status+".");
        }
    }
}

state off
{
    touch_start(integer num)
    {
        state default;
    }
}

Wikipedia script

If you want to run your own Wikipedia proxy, use this script and change the WIKIMEDIA_API constant:

<?php
/* Copyright (c) 2007, Katharine Berry
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Katharine Berry nor the names of any contributors
 *       may be used to endorse or promote products derived from this software
 *       without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY KATHARINE BERRY ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL KATHARINE BERRY BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ******************************************************************************/

function unhtmlentities($string)
{
    // replace numeric entities
    $string = preg_replace('~&#x([0-9a-f]+);~ei', 'chr(hexdec("\\1"))', $string);
    $string = preg_replace('~&#([0-9]+);~e', 'chr("\\1")', $string);
    // replace literal entities
    $trans_tbl = get_html_translation_table(HTML_ENTITIES);
    $trans_tbl = array_flip($trans_tbl);
    return strtr($string, $trans_tbl);
}

if($_GET['site'] == 'wikipedia')
{
	$search = stripslashes($_GET['query']);
	$url = str_replace(' ','_',$search);
	$text = file_get_contents("http://en.wikipedia.org/wiki/{$url}");
	$text = preg_replace('~</?[ai].*?>~is','',$text);
	$oldtext = $text;
	preg_match('~<title>(.+?) - Wikipedia, the free encyclopedia</title>~i',$text,$matches);
	$path = urlencode(str_replace(' ','_',$matches[1]));
	$title = $matches[1];
	while((strpos($oldtext,'</table>') < strpos($oldtext,'<p>') && strpos($oldtext,'</table>') !== false))
	{
		$oldtext = $text;
		$text = substr($text,strpos($text,'</table>')+8);
	}
	$oldtext = preg_replace('~<div class=.+?>.+?</div>~is','',$oldtext);
	if(!preg_match('~<p>([^<>]{0,15}<b>[^<>]+?</b>[^<>]{2,2}.+?)</p>~is',$oldtext,$matches))
	{
		preg_match('~<p>(.+?)</p>~is',$oldtext,$matches);
	}
	$lines = wordwrap(htmlentities(str_replace("\n",' ',preg_replace('~\[([0-9]+?|[a-z]+?needed)\]~is','',unhtmlentities(strip_tags($matches[0]))))),1000,"<br>",true);
	print "<result success=\"0\"><input>".htmlentities($search)."</input><that>".htmlentities($title).": {$lines}";
}
?>