2016-01-17 18:00:44 +00:00
// © 2013 the CatBase Authors under the WTFPL. See AUTHORS for the list of authors.
2013-12-10 23:37:07 +00:00
2012-08-26 19:15:04 +00:00
package plugins
import (
2016-01-17 15:29:30 +00:00
"database/sql"
2012-08-26 19:15:04 +00:00
"fmt"
2013-06-01 17:10:15 +00:00
"html/template"
"log"
2012-08-26 19:15:04 +00:00
"math/rand"
2013-06-01 17:10:15 +00:00
"net/http"
2012-08-26 19:15:04 +00:00
"regexp"
"strings"
"time"
2014-04-21 01:07:55 +00:00
2016-01-17 18:00:44 +00:00
"github.com/velour/catbase/bot"
2012-08-26 19:15:04 +00:00
)
2013-01-22 17:39:27 +00:00
// The factoid plugin provides a learning system to the bot so that it can
2012-08-29 16:50:52 +00:00
// respond to queries in a way that is unpredictable and fun
2012-08-26 19:15:04 +00:00
// factoid stores info about our factoid for lookup and later interaction
2016-01-17 15:29:30 +00:00
type factoid struct {
id sql . NullInt64
fact string
tidbit string
verb string
owner string
created time . Time
accessed time . Time
count int
}
func ( f * factoid ) save ( db * sql . DB ) error {
var err error
if f . id . Valid {
// update
_ , err = db . Exec ( ` update factoid set
fact = ? ,
tidbit = ? ,
verb = ? ,
owner = ? ,
accessed = ? ,
count = ?
where id = ? ` ,
f . fact ,
f . tidbit ,
f . verb ,
f . owner ,
f . accessed . Unix ( ) ,
f . count ,
f . id . Int64 )
} else {
f . created = time . Now ( )
f . accessed = time . Now ( )
// insert
res , err := db . Exec ( ` insert into factoid (
fact ,
tidbit ,
verb ,
owner ,
created ,
accessed ,
count
) values ( ? , ? , ? , ? , ? , ? , ? ) ; ` ,
f . fact ,
f . tidbit ,
f . verb ,
f . owner ,
f . created . Unix ( ) ,
f . accessed . Unix ( ) ,
f . count ,
)
if err != nil {
return err
}
id , err := res . LastInsertId ( )
// hackhackhack?
f . id . Int64 = id
f . id . Valid = true
}
return err
}
func ( f * factoid ) delete ( db * sql . DB ) error {
var err error
if f . id . Valid {
_ , err = db . Exec ( ` delete from factoid where id=? ` , f . id )
}
f . id . Valid = false
return err
}
func getFacts ( db * sql . DB , fact string ) ( [ ] * factoid , error ) {
var fs [ ] * factoid
rows , err := db . Query ( ` select
id ,
fact ,
tidbit ,
verb ,
owner ,
created ,
accessed ,
count
from factoid
where fact like ? ; ` ,
fact )
for rows . Next ( ) {
var f factoid
var tmpCreated int64
var tmpAccessed int64
err := rows . Scan (
& f . id ,
& f . fact ,
& f . tidbit ,
& f . verb ,
& f . owner ,
& tmpCreated ,
& tmpAccessed ,
& f . count ,
)
if err != nil {
return nil , err
}
f . created = time . Unix ( tmpCreated , 0 )
f . accessed = time . Unix ( tmpAccessed , 0 )
fs = append ( fs , & f )
}
return fs , err
}
func getSingle ( db * sql . DB ) ( * factoid , error ) {
var f factoid
var tmpCreated int64
var tmpAccessed int64
err := db . QueryRow ( ` select
id ,
fact ,
tidbit ,
verb ,
owner ,
created ,
accessed ,
count
from factoid
order by random ( ) limit 1 ; ` ) . Scan (
& f . id ,
& f . fact ,
& f . tidbit ,
& f . verb ,
& f . owner ,
& tmpCreated ,
& tmpAccessed ,
& f . count ,
)
f . created = time . Unix ( tmpCreated , 0 )
f . accessed = time . Unix ( tmpAccessed , 0 )
return & f , err
}
func getSingleFact ( db * sql . DB , fact string ) ( * factoid , error ) {
var f factoid
var tmpCreated int64
var tmpAccessed int64
err := db . QueryRow ( ` select
id ,
fact ,
tidbit ,
verb ,
owner ,
created ,
accessed ,
count
from factoid
where fact like ?
order by random ( ) limit 1 ; ` ,
fact ) . Scan (
& f . id ,
& f . fact ,
& f . tidbit ,
& f . verb ,
& f . owner ,
& tmpCreated ,
& tmpAccessed ,
& f . count ,
)
f . created = time . Unix ( tmpCreated , 0 )
f . accessed = time . Unix ( tmpAccessed , 0 )
return & f , err
2012-08-26 19:15:04 +00:00
}
2012-08-29 16:50:52 +00:00
// FactoidPlugin provides the necessary plugin-wide needs
2012-08-26 19:15:04 +00:00
type FactoidPlugin struct {
2012-08-26 20:15:50 +00:00
Bot * bot . Bot
NotFound [ ] string
2016-01-17 15:29:30 +00:00
LastFact * factoid
db * sql . DB
2012-08-26 19:15:04 +00:00
}
// NewFactoidPlugin creates a new FactoidPlugin with the Plugin interface
2013-08-28 01:52:27 +00:00
func NewFactoidPlugin ( botInst * bot . Bot ) * FactoidPlugin {
2012-08-26 19:15:04 +00:00
p := & FactoidPlugin {
2016-01-17 15:29:30 +00:00
Bot : botInst ,
2012-08-26 20:15:50 +00:00
NotFound : [ ] string {
"I don't know." ,
"NONONONO" ,
"((" ,
"*pukes*" ,
"NOPE! NOPE! NOPE!" ,
"One time, I learned how to jump rope." ,
} ,
2016-01-17 15:29:30 +00:00
db : botInst . DB ,
}
_ , err := p . db . Exec ( ` create table if not exists factoid (
id integer primary key ,
fact string ,
tidbit string ,
verb string ,
owner string ,
created integer ,
accessed integer ,
count integer
) ; ` )
if err != nil {
log . Fatal ( err )
2012-08-26 19:15:04 +00:00
}
2016-01-17 15:29:30 +00:00
2013-08-28 01:52:27 +00:00
for _ , channel := range botInst . Config . Channels {
2012-08-27 15:34:21 +00:00
go p . factTimer ( channel )
2013-08-28 01:52:27 +00:00
go func ( ) {
// Some random time to start up
2013-09-01 02:29:13 +00:00
time . Sleep ( time . Duration ( 15 ) * time . Second )
2013-08-28 01:52:27 +00:00
if ok , fact := p . findTrigger ( p . Bot . Config . StartupFact ) ; ok {
p . sayFact ( bot . Message {
Channel : channel ,
2016-01-17 15:29:30 +00:00
Body : "speed test" , // BUG: This is defined in the config too
2013-08-28 01:52:27 +00:00
Command : true ,
Action : false ,
} , * fact )
}
} ( )
2012-08-27 15:34:21 +00:00
}
2013-08-28 01:52:27 +00:00
2012-08-26 19:15:04 +00:00
return p
}
2012-08-29 16:50:52 +00:00
// findAction simply regexes a string for the action verb
func findAction ( message string ) string {
2012-11-11 16:08:37 +00:00
r , err := regexp . Compile ( "<.+?>" )
2012-08-26 19:15:04 +00:00
if err != nil {
panic ( err )
}
action := r . FindString ( message )
2013-09-05 01:56:03 +00:00
if action == "" {
if strings . Contains ( message , " is " ) {
return "is"
} else if strings . Contains ( message , " are " ) {
return "are"
}
}
2012-08-26 19:15:04 +00:00
return action
}
2012-08-29 16:50:52 +00:00
// learnFact assumes we have a learning situation and inserts a new fact
// into the database
2016-01-17 15:29:30 +00:00
func ( p * FactoidPlugin ) learnFact ( message bot . Message , fact , verb , tidbit string ) bool {
verb = strings . ToLower ( verb )
2012-08-26 20:15:50 +00:00
2016-01-17 15:29:30 +00:00
var count sql . NullInt64
err := p . db . QueryRow ( ` select count ( * ) from factoid
where fact = ? and verb = ? and tidbit = ? ` ,
fact , verb , tidbit ) . Scan ( & count )
if err != nil {
log . Println ( "Error counting facts: " , err )
return false
} else if count . Valid && count . Int64 != 0 {
log . Println ( "User tried to relearn a fact." )
2012-08-26 20:15:50 +00:00
return false
}
2016-01-17 15:29:30 +00:00
n := factoid {
fact : fact ,
tidbit : tidbit ,
verb : verb ,
owner : message . User . Name ,
created : time . Now ( ) ,
accessed : time . Now ( ) ,
count : 0 ,
}
p . LastFact = & n
err = n . save ( p . db )
2012-08-27 15:34:21 +00:00
if err != nil {
2016-01-17 15:29:30 +00:00
log . Println ( "Error inserting fact: " , err )
return false
2012-08-27 15:34:21 +00:00
}
2012-08-26 20:15:50 +00:00
return true
2012-08-26 19:15:04 +00:00
}
2012-08-29 16:50:52 +00:00
// findTrigger checks to see if a given string is a trigger or not
2016-01-17 15:29:30 +00:00
func ( p * FactoidPlugin ) findTrigger ( fact string ) ( bool , * factoid ) {
fact = strings . ToLower ( fact ) // TODO: make sure this needs to be lowered here
2012-08-26 19:15:04 +00:00
2016-01-17 15:29:30 +00:00
f , err := getSingleFact ( p . db , fact )
if err != nil {
2012-08-26 20:15:50 +00:00
return false , nil
2012-08-26 19:15:04 +00:00
}
2016-01-17 15:29:30 +00:00
return true , f
2012-08-26 20:15:50 +00:00
}
2012-08-29 16:50:52 +00:00
// sayFact spits out a fact to the channel and updates the fact in the database
// with new time and count information
2016-01-17 15:29:30 +00:00
func ( p * FactoidPlugin ) sayFact ( message bot . Message , fact factoid ) {
msg := p . Bot . Filter ( message , fact . tidbit )
full := p . Bot . Filter ( message , fmt . Sprintf ( "%s %s %s" ,
fact . fact , fact . verb , fact . tidbit ,
) )
2012-08-27 15:34:21 +00:00
for i , m := 0 , strings . Split ( msg , "$and" ) ; i < len ( m ) && i < 4 ; i ++ {
msg := strings . TrimSpace ( m [ i ] )
if len ( msg ) == 0 {
continue
}
2016-01-17 15:29:30 +00:00
if fact . verb == "action" {
2012-08-27 15:34:21 +00:00
p . Bot . SendAction ( message . Channel , msg )
2016-01-17 15:29:30 +00:00
} else if fact . verb == "reply" {
2012-08-27 15:34:21 +00:00
p . Bot . SendMessage ( message . Channel , msg )
2016-01-17 15:29:30 +00:00
} else {
p . Bot . SendMessage ( message . Channel , full )
2012-08-27 15:34:21 +00:00
}
}
2012-08-29 14:24:34 +00:00
// update fact tracking
2016-01-17 15:29:30 +00:00
fact . accessed = time . Now ( )
fact . count += 1
err := fact . save ( p . db )
2012-08-29 14:24:34 +00:00
if err != nil {
2016-01-17 15:29:30 +00:00
log . Printf ( "Could not update fact.\n" )
log . Printf ( "%#v\n" , fact )
log . Println ( err )
2012-08-29 14:24:34 +00:00
}
2012-08-29 16:50:52 +00:00
p . LastFact = & fact
2012-08-27 15:34:21 +00:00
}
2012-08-29 16:50:52 +00:00
// trigger checks the message for its fitness to be a factoid and then hauls
// the message off to sayFact for processing if it is in fact a trigger
2012-08-26 20:15:50 +00:00
func ( p * FactoidPlugin ) trigger ( message bot . Message ) bool {
2012-08-27 15:34:21 +00:00
if len ( message . Body ) > 4 || message . Command || message . Body == "..." {
2012-08-26 20:15:50 +00:00
if ok , fact := p . findTrigger ( message . Body ) ; ok {
2012-08-27 15:34:21 +00:00
p . sayFact ( message , * fact )
2012-08-26 20:15:50 +00:00
return true
}
2012-12-30 16:26:26 +00:00
r := strings . NewReplacer ( "'" , "" , "\"" , "" , "," , "" , "." , "" , ":" , "" ,
2013-01-07 21:08:34 +00:00
"?" , "" , "!" , "" )
2012-11-11 16:14:40 +00:00
if ok , fact := p . findTrigger ( r . Replace ( message . Body ) ) ; ok {
p . sayFact ( message , * fact )
return true
}
2012-08-26 20:15:50 +00:00
}
return false
2012-08-26 19:15:04 +00:00
}
2012-08-29 16:50:52 +00:00
// tellThemWhatThatWas is a hilarious name for a function.
func ( p * FactoidPlugin ) tellThemWhatThatWas ( message bot . Message ) bool {
2012-08-29 21:06:15 +00:00
fact := p . LastFact
var msg string
if fact == nil {
msg = "Nope."
} else {
msg = fmt . Sprintf ( "That was (#%d) '%s <%s> %s'" ,
2016-01-17 15:29:30 +00:00
fact . id , fact . fact , fact . verb , fact . tidbit )
2012-08-29 21:06:15 +00:00
}
p . Bot . SendMessage ( message . Channel , msg )
return true
2012-08-29 16:50:52 +00:00
}
2012-08-29 21:06:15 +00:00
func ( p * FactoidPlugin ) learnAction ( message bot . Message , action string ) bool {
2012-08-29 16:50:52 +00:00
body := message . Body
parts := strings . SplitN ( body , action , 2 )
// This could fail if is were the last word or it weren't in the sentence (like no spaces)
if len ( parts ) != 2 {
return false
2012-08-27 15:34:21 +00:00
}
2012-08-29 16:50:52 +00:00
trigger := strings . TrimSpace ( parts [ 0 ] )
fact := strings . TrimSpace ( parts [ 1 ] )
action = strings . TrimSpace ( action )
if len ( trigger ) == 0 || len ( fact ) == 0 || len ( action ) == 0 {
p . Bot . SendMessage ( message . Channel , "I don't want to learn that." )
return true
2012-08-26 19:15:04 +00:00
}
2012-08-29 16:50:52 +00:00
if len ( strings . Split ( fact , "$and" ) ) > 4 {
p . Bot . SendMessage ( message . Channel , "You can't use more than 4 $and operators." )
return true
}
2012-08-26 19:15:04 +00:00
2012-08-29 16:50:52 +00:00
strippedaction := strings . Replace ( strings . Replace ( action , "<" , "" , 1 ) , ">" , "" , 1 )
2012-08-26 19:15:04 +00:00
2012-08-29 16:50:52 +00:00
if p . learnFact ( message , trigger , strippedaction , fact ) {
p . Bot . SendMessage ( message . Channel , fmt . Sprintf ( "Okay, %s." , message . User . Name ) )
} else {
p . Bot . SendMessage ( message . Channel , "I already know that." )
}
2012-08-26 20:35:13 +00:00
2012-08-29 16:50:52 +00:00
return true
}
2012-08-26 19:40:57 +00:00
2013-03-18 21:44:49 +00:00
// Checks body for the ~= operator returns it
func changeOperator ( body string ) string {
if strings . Contains ( body , "=~" ) {
return "=~"
} else if strings . Contains ( body , "~=" ) {
return "~="
}
return ""
2012-08-29 16:50:52 +00:00
}
2012-08-26 19:15:04 +00:00
2012-08-29 16:50:52 +00:00
// If the user requesting forget is either the owner of the last learned fact or
// an admin, it may be deleted
func ( p * FactoidPlugin ) forgetLastFact ( message bot . Message ) bool {
if p . LastFact == nil {
2012-08-29 21:06:15 +00:00
p . Bot . SendMessage ( message . Channel , "I refuse." )
2012-08-29 16:50:52 +00:00
return true
}
2016-01-17 15:29:30 +00:00
if message . User . Admin || message . User . Name == p . LastFact . owner {
err := p . LastFact . delete ( p . db )
2012-08-29 16:50:52 +00:00
if err != nil {
2016-01-17 15:29:30 +00:00
log . Println ( "Error removing fact: " , p . LastFact , err )
2012-08-26 20:15:50 +00:00
}
2016-01-17 15:29:30 +00:00
fmt . Printf ( "Forgot #%d: %s %s %s\n" , p . LastFact . id , p . LastFact . fact ,
p . LastFact . verb , p . LastFact . tidbit )
2012-08-29 21:06:15 +00:00
p . Bot . SendAction ( message . Channel , "hits himself over the head with a skillet" )
2012-08-29 16:50:52 +00:00
p . LastFact = nil
} else {
p . Bot . SendMessage ( message . Channel , "You don't own that fact." )
}
2012-08-26 19:15:04 +00:00
2012-08-29 16:50:52 +00:00
return true
}
// Allow users to change facts with a simple regexp
func ( p * FactoidPlugin ) changeFact ( message bot . Message ) bool {
2013-03-18 21:44:49 +00:00
oper := changeOperator ( message . Body )
parts := strings . SplitN ( message . Body , oper , 2 )
2012-08-29 21:06:15 +00:00
userexp := strings . TrimSpace ( parts [ 1 ] )
trigger := strings . TrimSpace ( parts [ 0 ] )
parts = strings . Split ( userexp , "/" )
if len ( parts ) == 4 {
// replacement
if parts [ 0 ] != "s" {
p . Bot . SendMessage ( message . Channel , "Nah." )
}
find := parts [ 1 ]
replace := parts [ 2 ]
// replacement
2016-01-17 15:29:30 +00:00
result , err := getFacts ( p . db , trigger )
if err != nil {
log . Println ( "Error getting facts: " , trigger , err )
}
if ! ( message . User . Admin && userexp [ len ( userexp ) - 1 ] == 'g' ) {
result = result [ : 1 ]
if result [ 0 ] . owner != message . User . Name && ! message . User . Admin {
2012-08-29 21:17:30 +00:00
p . Bot . SendMessage ( message . Channel , "That's not your fact to edit." )
return true
}
2012-08-29 21:06:15 +00:00
}
// make the changes
msg := fmt . Sprintf ( "Changing %d facts." , len ( result ) )
p . Bot . SendMessage ( message . Channel , msg )
reg , err := regexp . Compile ( find )
if err != nil {
p . Bot . SendMessage ( message . Channel , "I don't really want to." )
return false
}
for _ , fact := range result {
2016-01-17 15:29:30 +00:00
fact . fact = reg . ReplaceAllString ( fact . fact , replace )
fact . fact = strings . ToLower ( fact . fact )
fact . verb = reg . ReplaceAllString ( fact . verb , replace )
fact . tidbit = reg . ReplaceAllString ( fact . tidbit , replace )
fact . count += 1
fact . accessed = time . Now ( )
fact . save ( p . db )
2012-08-29 21:06:15 +00:00
}
} else if len ( parts ) == 3 {
// search for a factoid and print it
2016-01-17 15:29:30 +00:00
result , err := getFacts ( p . db , trigger )
if err != nil {
log . Println ( "Error getting facts: " , trigger , err )
}
count := len ( result )
2012-08-29 21:06:15 +00:00
if parts [ 2 ] == "g" {
// summarize
2016-01-17 15:29:30 +00:00
result = result [ : 4 ]
2012-08-29 21:06:15 +00:00
} else {
2016-01-17 15:29:30 +00:00
p . sayFact ( message , * result [ 0 ] )
2012-08-29 21:06:15 +00:00
return true
}
msg := fmt . Sprintf ( "%s " , trigger )
for i , fact := range result {
if i != 0 {
msg = fmt . Sprintf ( "%s |" , msg )
}
2016-01-17 15:29:30 +00:00
msg = fmt . Sprintf ( "%s <%s> %s" , msg , fact . verb , fact . tidbit )
2012-08-29 21:06:15 +00:00
}
if count > 4 {
msg = fmt . Sprintf ( "%s | ...and %d others" , msg , count )
}
p . Bot . SendMessage ( message . Channel , msg )
} else {
p . Bot . SendMessage ( message . Channel , "I don't know what you mean." )
}
2012-08-29 16:50:52 +00:00
return true
}
// Message responds to the bot hook on recieving messages.
// This function returns true if the plugin responds in a meaningful way to the users message.
// Otherwise, the function returns false and the bot continues execution of other plugins.
func ( p * FactoidPlugin ) Message ( message bot . Message ) bool {
if strings . ToLower ( message . Body ) == "what was that?" {
return p . tellThemWhatThatWas ( message )
}
// This plugin has no business with normal messages
if ! message . Command {
// look for any triggers in the db matching this message
return p . trigger ( message )
}
2013-06-01 20:46:16 +00:00
if strings . ToLower ( message . Body ) == "factoid" {
if fact := p . randomFact ( ) ; fact != nil {
p . sayFact ( message , * fact )
return true
} else {
log . Println ( "Got a nil fact." )
}
}
2013-01-22 19:46:51 +00:00
if strings . ToLower ( message . Body ) == "forget that" {
2012-08-29 16:50:52 +00:00
return p . forgetLastFact ( message )
}
2013-03-18 21:44:49 +00:00
if changeOperator ( message . Body ) != "" {
2012-08-29 16:50:52 +00:00
return p . changeFact ( message )
}
action := findAction ( message . Body )
if action != "" {
return p . learnAction ( message , action )
2012-08-26 19:15:04 +00:00
}
// look for any triggers in the db matching this message
2012-08-26 20:15:50 +00:00
if p . trigger ( message ) {
2012-08-26 19:15:04 +00:00
return true
}
2012-08-29 16:50:52 +00:00
// We didn't find anything, panic!
2012-08-26 20:15:50 +00:00
p . Bot . SendMessage ( message . Channel , p . NotFound [ rand . Intn ( len ( p . NotFound ) ) ] )
2012-08-26 19:15:04 +00:00
return true
}
// Help responds to help requests. Every plugin must implement a help function.
func ( p * FactoidPlugin ) Help ( channel string , parts [ ] string ) {
2012-08-26 19:29:34 +00:00
p . Bot . SendMessage ( channel , "I can learn facts and spit them back out. You can say \"this is that\" or \"he <has> $5\". Later, trigger the factoid by just saying the trigger word, \"this\" or \"he\" in these examples." )
p . Bot . SendMessage ( channel , "I can also figure out some variables including: $nonzero, $digit, $nick, and $someone." )
2012-08-26 19:15:04 +00:00
}
// Empty event handler because this plugin does not do anything on event recv
func ( p * FactoidPlugin ) Event ( kind string , message bot . Message ) bool {
return false
}
2012-08-27 15:34:21 +00:00
2012-08-29 16:50:52 +00:00
// Pull a fact at random from the database
2016-01-17 15:29:30 +00:00
func ( p * FactoidPlugin ) randomFact ( ) * factoid {
f , err := getSingle ( p . db )
2012-08-27 15:34:21 +00:00
if err != nil {
2016-01-17 15:29:30 +00:00
fmt . Println ( "Error getting a fact: " , err )
2013-06-01 20:46:16 +00:00
return nil
2012-08-27 15:34:21 +00:00
}
2016-01-17 15:29:30 +00:00
return f
2012-08-27 15:34:21 +00:00
}
2012-08-29 16:50:52 +00:00
// factTimer spits out a fact at a given interval and with given probability
2012-08-27 15:34:21 +00:00
func ( p * FactoidPlugin ) factTimer ( channel string ) {
2012-10-11 20:28:00 +00:00
duration := time . Duration ( p . Bot . Config . QuoteTime ) * time . Minute
myLastMsg := time . Now ( )
2012-08-27 15:34:21 +00:00
for {
2012-10-11 20:28:00 +00:00
time . Sleep ( time . Duration ( 5 ) * time . Second )
2013-06-17 01:03:43 +00:00
lastmsg , err := p . Bot . LastMessage ( channel )
2012-10-11 20:28:00 +00:00
if err != nil {
continue
}
tdelta := time . Since ( lastmsg . Time )
earlier := time . Since ( myLastMsg ) > tdelta
chance := rand . Float64 ( )
success := chance < p . Bot . Config . QuoteChance
if success && tdelta > duration && earlier {
2012-08-27 15:34:21 +00:00
fact := p . randomFact ( )
if fact == nil {
continue
}
// we need to fabricate a message so that bot.Filter can operate
message := bot . Message {
User : & p . Bot . Users [ rand . Intn ( len ( p . Bot . Users ) ) ] ,
Channel : channel ,
}
p . sayFact ( message , * fact )
2012-10-11 20:28:00 +00:00
myLastMsg = time . Now ( )
2012-08-27 15:34:21 +00:00
}
}
}
2013-05-08 00:08:18 +00:00
// Handler for bot's own messages
func ( p * FactoidPlugin ) BotMessage ( message bot . Message ) bool {
return false
}
2013-06-01 17:10:15 +00:00
// Register any web URLs desired
func ( p * FactoidPlugin ) RegisterWeb ( ) * string {
http . HandleFunc ( "/factoid/req" , p . serveQuery )
2013-06-01 18:40:06 +00:00
http . HandleFunc ( "/factoid" , p . serveQuery )
2013-06-01 17:10:15 +00:00
tmp := "/factoid"
return & tmp
}
2013-06-01 21:24:05 +00:00
func linkify ( text string ) template . HTML {
parts := strings . Split ( text , " " )
for i , word := range parts {
if strings . HasPrefix ( word , "http" ) {
parts [ i ] = fmt . Sprintf ( "<a href=\"%s\">%s</a>" , word , word )
}
}
return template . HTML ( strings . Join ( parts , " " ) )
}
2013-06-01 17:10:15 +00:00
func ( p * FactoidPlugin ) serveQuery ( w http . ResponseWriter , r * http . Request ) {
context := make ( map [ string ] interface { } )
2013-06-01 21:24:05 +00:00
funcMap := template . FuncMap {
// The name "title" is what the function will be called in the template text.
"linkify" : linkify ,
}
2013-06-01 20:20:45 +00:00
if e := r . FormValue ( "entry" ) ; e != "" {
2016-01-17 17:20:16 +00:00
entries , err := getFacts ( p . db , e )
if err != nil {
log . Println ( "Web error searching: " , err )
}
2013-06-01 18:17:13 +00:00
context [ "Count" ] = fmt . Sprintf ( "%d" , len ( entries ) )
2013-06-01 17:10:15 +00:00
context [ "Entries" ] = entries
2013-06-01 17:29:12 +00:00
context [ "Search" ] = e
2013-06-01 17:10:15 +00:00
}
2013-06-01 21:24:05 +00:00
t , err := template . New ( "factoidIndex" ) . Funcs ( funcMap ) . Parse ( factoidIndex )
2013-06-01 17:10:15 +00:00
if err != nil {
log . Println ( err )
}
t . Execute ( w , context )
}