# ImDB Quotes
#
# Description: Pulls quotes from ImDB
#
# Features: Movie/Show Specific Quotes, offline database building
# of pulled quotes for more advanced searching. Builds local database from 
# movie favorites specified.
#
# Usage: 
#		!imdbq -list ?-c##? ?-e? <movie title>
#			This Displays movies/shows and there imdb ID's for use 
#			with the -add function to mass add quotes.
#			Use -cX with X = Number of results to show, to limit results.
#			Use -e to force exact result matching.
#		!imdbq -random
#			Plays a random quote pulled from imdb.com.
#		!imdbq -add <imdb ID>
#			Enters entire database of quotes from the show/movie
#			specified.
#		!imdbq -del <Show Title>
#			Searchs and deletes shows matching pattern given.
#		!imdbq -info
#			Displays Number of entries for each show as well as
#			a grand total of entries among all shows.
#		!imdbq
#			By itself it will pull from the local database or
#			will pull randomly depending on your options set.
#
# Edit below parameters to start automatic timer functions.
#
#


#This will turn on local saving which can be used for creating a custom
#quote database from particular shows/movies you enjoy. [0 = Off, 1 = On]
set imdb_quotes(local) 1

#Spit Random quotes on a timer? (If local saving is turned on local quotes are used)
#[0 = Off, XXX = Minutes between Announces]
set imdb_quotes(random) 60

#If random quotes are to be sent to which channels?
set imdb_quotes(random_chans) {
 #the-matrix
}

#Should we default all output to Private Notice? [0 = No, 1 = Yes]
set imdb_quotes(private) 0

#Maximum number of Shows/Movies to display by default?
#(Pokemon will give you like 40+ results)
set imdb_quotes(MAX) 4

#Flags allowed to Add local quotes to the bot. 
set imdb_quotes(add_flag) "m"

#Flags allowed to Delete local quotes to the bot.
set imdb_quotes(del_flag) "m"

#Should the bot try to perform its own secondary exact search
#on the results by default? (You can always use -e to force exact searches)
#[0 = No, 1 = Yes]
set imdb_quotes(exact) "0"



set imdb_quotes(ver) v1.2a

if {$imdb_quotes(random)>0} {
  set i_timer 1
  foreach timer [timers] { if {[lindex [lindex $timer 1] 0]=="pub_imdb_quotes"} { set i_timer 0 } }
  if {$i_timer} { timer $imdb_quotes(random) "pub_imdb_quotes . . . timer \"\"" }
}



bind pub -|- !imdbq pub_imdb_quotes

proc save_imdb_quotes {} {
  global imdb_quotes
  set wfile [open scripts/imdb_quotes.dat w]
  foreach q $imdb_quotes(saved) {
    puts $wfile [html_replace $q]
  }
  close $wfile
}

proc load_imdb_quotes {} {
  global imdb_quotes
  if {![file exists scripts/imdb_quotes.dat]} {
    set wfile [open scripts/imdb_quotes.dat w]
    puts $wfile ""
    close $wfile
  }
  set rfile [open scripts/imdb_quotes.dat r]
  catch {unset imdb_quotes(saved)}
  while {![eof $rfile]} {
    set line [gets $rfile]
    if {$line==""} { continue }
    lappend imdb_quotes(saved) $line
  }
  close $rfile
  if {![info exists imdb_quotes(saved)]} { set imdb_quotes(saved) "" }
}

load_imdb_quotes

proc check_line {line} {
  set tries 0
  set buffer ""
  set nextline ""
  while {[string length $line]>360} {
    if {$tries>4} { break }
    if {[regexp {(.*[.?!])([^.]{15,}[.?!]?)} $line match newline nextline]} {
      if {$nextline!=""} {
	set line $newline
	lappend buffer $nextline
	set nextline ""
      }
    }
    incr tries
  }
  return [linsert $buffer 0 $line]
}

proc html_replace {quotes} {
  regsub -all {Â‘|Â‘} $quotes "\`" quotes
  regsub -all {Â’|Â’} $quotes "\'" quotes
  foreach index [lsort -decreasing [regexp -all -indices -inline {&#[0-9]+;} $quotes]] {
     set binary_value [string range $quotes [lindex $index 0] [lindex $index 1]]
     regexp {[0-9]+} $binary_value match
     set quotes [string replace $quotes [lindex $index 0] [lindex $index 1] [format %c $match]]
  }
  return $quotes
}

proc get_imdb_quotes {private where nick function max exact show} {
  global tokens
  package require http
  http::config -useragent "Mozilla/5.0"
  set search $show
  if {$show!=""} {
    regsub -all " " $show "+" show
  }
  switch $function {
    random { set url http://us.imdb.com/Sections/Quotes/ }
    list { set url http://us.imdb.com/find?tt=on\;nm=on\;q=$show }
    add { set url http://us.imdb.com/title/tt$show/quotes }
  }
  set conn [http::geturl $url -command spit_imdb_quotes]
  set tokens($conn) "$private $where $nick [unixtime] $function $max $exact $search" 
}

proc spit_imdb_quotes {token} {
  global tokens imdb_quotes
  set private [lindex $tokens($token) 0]
  set where [lindex $tokens($token) 1]
  set unixtime [lindex $tokens($token) 3]
  set function [lindex $tokens($token) 4]
  set max [lindex $tokens($token) 5]
  set exact [lindex $tokens($token) 6]
  set search_term [lrange $tokens($token) 7 end]
  unset tokens($token)
  upvar #0 $token http
  if {$http(status)=="error"} {
    if {$http(error)!=""} {
      putserv  "$private $where :Error: $http(error)"
      return 0
    }
  }
  if {$http(status)=="timeout"} {
    putserv "$private $where :Error: Timeout."
    return 0
  }
  catch {
	  switch $function {
    random {
      foreach line [split $http(body) \n] {
        if {[string match *BLOQUOTE* $line]} {
          regsub -all {<[^>]*>} $line {} line
          regexp {(.*)from:(.*)} $line match quotes movie
          break
        }
      }
      if {$private=="PRIVMSG" && $where=="timer"} { foreach where $imdb_quotes(random_chans) { putserv "$private $where :\002$movie\002 - $quotes" } } else {
	putserv "$private $where :\002$movie\002 - $quotes"
      }
    }
    list {
      foreach line [split $http(body) \n] {
	if {[regexp {href=\"/title/tt([0-9]*)/\">([^<]*)(.*?aka <i>"?([^<"]*)"?)?} $line regexp title_number title_name aka_match aka_title]} {
	  set shows($title_number) $title_name
	  lappend show_list $title_number
	}
      }
      set buffer_list "" ; set ebuffer_list ""
      set cur_count 0
      if {$max!=""} { set max_incr 1 } else { set max 0 }
      if {![info exists shows]} {
        putserv "$private $where :No Results."
      } else {
	  if {$exact} {
	    set show_len [llength [array names shows]]
	    if {$show_len>$max} {
	      foreach show [$show_list] {
	        set match 0
	        foreach term [string tolower $search_term] {
		  if {[string match *$term* [string tolower $shows($show)]]} { set match 1 } else { set match 0 }
	        }
	        if {$match} {
	          set exp ^.?[string tolower $search_term].?.?\\\(\[?0-9\]*\\\).*
		  if {[regexp $exp [string tolower $shows($show)]]} { lappend ebuffer_list $show } else {
		    lappend buffer_list $show
		  }
		  set index [lsearch -exact $show_list $show]
		  set show_list [lreplace $show_list $index $index]
	        }
	      }
	    }
	    set full_list $ebuffer_list
	    append full_list " " $buffer_list
	    append full_list " " $show_list
	  } else { set full_list $show_list }
	  foreach show $full_list {
	    incr cur_count $max_incr
	    if {$cur_count>$max} { break }
	    putserv "$private $where :\002[html_replace $shows($show)]\002 \037\[ $show \]\037"
	  }
	}
    }
    add {
      regexp -nocase {<strong[^>]*>(.*)</strong>} $http(body) match show
      if {![info exists show]} {
	putserv "$private $where :Couldn't find quotes for that show"
	return 0
      }
      regsub -all {<[^>]*>|\n} $show {} show
      set show [html_replace $show]
      regexp -nocase {<a name=\"qt[0-9]*\">(.*)<p [^>]*>} $http(body) match quotes
      regsub {</P>.*} $quotes {} quotes
      regsub -all {<hr width=\"30%\">} $quotes \002 quotes
      regsub -all {<br>} $quotes |BR| quotes
      regsub -all {<p align=\"center\">\|BR\|Browse titles.*} $quotes {} quotes
      regsub -all {<[^>]*>|\n} $quotes {} quotes
      regsub -all : $quotes ": " quotes
      set quotes [html_replace $quotes]
      set cnt 0
      foreach quote [split $quotes \002] {
	lappend imdb_quotes(saved) "$show||$quote"
	incr cnt
      }
      save_imdb_quotes
      putserv "$private $where :\002$cnt\002 Quotes added from \002$show\002"
    }
  }
  } err
  if {$err!=""} { putlog "Error: $err" }
}

proc pub_imdb_quotes {nick uhost hand chan arg} {
  global imdb_quotes tokens randnum
  set private 0
  set function random
  set exact $imdb_quotes(exact)
  if {$imdb_quotes(local)} {
    set function local
  }
  if {$imdb_quotes(private) && $hand=="*"} { set private 1 }
  if {[set index [lsearch -exact $arg -del]]!="-1"} {
    set function "delete"
    set arg [lreplace $arg $index $index]
    if {![matchattr $hand $imdb_quotes(del_flag)]} {
      putnot $nick "You don't have access to -del, your a peasant don't you see?"
      return 0
    }
    if {$arg==""} {
      putnot $nick "Usage: !imdbq -del <Search Terms>"
      return 0
    }
  }
  if {[set index [lsearch -exact $arg -p]]!="-1"} {
    set private 1
    set arg [lreplace $arg $index $index]
  }
  if {[set index [lsearch -exact $arg -random]]!="-1"} {
    set function "random"
    set arg [lreplace $arg $index $index]
  }
  if {[set index [lsearch -exact $arg -list]]!="-1"} {
    set function "list"
    set arg [lreplace $arg $index $index]
    if {$arg==""} {
      putnot $nick "Usage: !imdbq -list ?-c##? ?-e? <search terms>"
      return 0
    }
    set max $imdb_quotes(MAX)
    if {[set index [lsearch -regexp $arg {-c[0-9]*}]]!="-1"} {
      set max [string range [lindex $arg $index] 2 end]
      set arg [lreplace $arg $index $index]
      regsub -all {[^0-9]} $max "" max
      if {$max==""} {
	putnot $nick "Invalid count Flag number specified (Use a integer)"
	return 0
      }
    }
    if {[set index [lsearch -exact $arg -e]]!="-1"} {
      set exact 1
      set arg [lreplace $arg $index $index]
    }
  }
  if {[set index [lsearch -exact $arg -info]]!="-1"} {
    set function "info"
    set arg [lreplace $arg $index $index]
  }
  if {[set index [lsearch -exact $arg -add]]!="-1"} {
    if {!$imdb_quotes(local)} {
      putnot $nick "Local Quote Storing has been turned off. Please bother the bot owner."
      return 0
    }
    set function "add"
    if {![matchattr $hand $imdb_quotes(add_flag)]} {
      putnot $nick "You don't have access to -add, your a peasant don't you see?"
      return 0
    }
    set arg [lreplace $arg $index $index]
    if {$arg==""} {
      putnot $nick "Usage: !imdbq -add <imdb Show ID>"
      return 0
    }
    if {[regexp {[^0-9]} $arg]} {
      putnot $nick "Invalid Show ID!"
      return 0
    }
  }
  foreach array [array names tokens] {
    if {$nick==[lindex $tokens($array) 2]} {
      if {[expr [unixtime] - [lindex $tokens($array) 3]]>300} {
        unset tokens($array)
      } else {
          putnot $nick "You already have one query open wait a couple, go to blockbuster."
          return 0
        }
    }
  }
  if {($chan=="timer") && ($imdb_quotes(random)>0)} {
    timer $imdb_quotes(random) "pub_imdb_quotes . . . timer \"\""
    set private 0
  }
  if {$private} {
    set type "NOTICE"
  } else {
      set type "PRIVMSG"
    }
  if {$function=="delete"} {
    regsub -all {^|$| } $arg "*" arg
    set quotes ""
    foreach quote $imdb_quotes(saved) {
      regexp {(.*)\|\|} $quote match show
      regsub -all \" $show {} show
      if {![string match $arg $show]} { lappend quotes $quote }
    }
    if {[llength $quotes]==[llength $imdb_quotes(saved)]} { putnot $nick "Match not found!" ; return 0 }
    putnot $nick "Deleted \002[expr [llength $imdb_quotes(saved)] - [llength $quotes]]\002 entries"
    set imdb_quotes(saved) $quotes
    return 1
  }
  if {$function=="info"} {
    foreach quote $imdb_quotes(saved) {
      regexp {(.*)\|\|} $quote match show
      regsub -all \" $show {} show
      regsub -all " " $show "_" show
      if {![info exists shows($show)]} {
	set shows($show) 1
      } else { incr shows($show) }
    }
    set grandtotal 0
    foreach show [array names shows] {
      regsub -all "_" $show " " n_show
      putnot $nick "\002$n_show\002 has $shows($show) entries"
      incr grandtotal $shows($show)
    }
    putnot $nick "A grandtotal of \[\002$grandtotal\002\] entries"
    return 1
  }
  if {$function=="local"} {
    if {![info exists randnum]} { set randnum "" }
    set quotes $imdb_quotes(saved)
    if {$arg!=""} {
      regsub -all {^|$| } $arg "*" arg
      set quotes ""
      foreach quote $imdb_quotes(saved) {
        regexp {(.*)\|\|} $quote match show
        regsub -all \" $show {} show
	if {[string match [string tolower $arg] [string tolower $show]]} { lappend quotes $quote }
      }
      if {$quotes==""} { putnot $nick "Match not found!" ; return 0 }
    }
    if {[llength $quotes]<1} {
      putnot $nick "You don't have any locally saved quotes please add some using !imdbq -add <imdb Show ID>"
      return 0
    }
    set newrandnum [rand [llength $quotes]]
    while {$newrandnum==$randnum} {
      set newrandnum [rand [llength $quotes]]
    }
    set randnum $newrandnum
    regexp {(.*)\|\|(.*)} [lindex $quotes $randnum] match show quote
    regsub -all {\|BR\|} $quote \002 quote
    set show "\002$show\002 - "
    if {$private} {
      set go 0
      foreach line [split $quote \002] {
	if {$line==""} { continue }
	if {[string length $line]>360} {
	  set line [check_line $line]
	  foreach ln $line { putserv "NOTICE $nick :$show $ln" ; set show "" }
	} else {
	    putserv "NOTICE $nick :$show $line"
	  }
	if {!$go} { set show "" ; set go 1 }
      }
    } else {
        set go 0
        foreach line [split $quote \002] {
	  if {$line==""} { continue }
	  if {[string length $line]>360} {
	    set line [check_line $line]
	    if {$chan=="timer"} {
	      foreach ln $line { foreach chan $imdb_quotes(random_chans) { putserv "PRIVMSG $chan :$show $ln" } ; set show "" }
	      set chan "timer"
	    } else {
		foreach ln $line { putserv "PRIVMSG $chan :$show $ln" ; set show "" }
	      }
	  } else {

  	  if {$chan=="timer"} {
            foreach chan $imdb_quotes(random_chans) { putserv "PRIVMSG $chan :$show $line" }
	    set chan "timer"
	  } else {
	      putserv "PRIVMSG $chan :$show $line"
	    }

	  }
  	  if {!$go} { set show "" ; set go 1 }
        }
      }
  } else {
      if {![info exists max]} { set max "" }
      get_imdb_quotes $type $chan $nick $function $max $exact $arg
    }
  return 1
}

putlog "ImDB Quotes query tools for eggdrop"