wiki.tcl 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #
  2. # edited Jun 27 2017 for https by genewitch
  3. #
  4. # Mar 30 2010
  5. # by horgh
  6. #
  7. # Requires Tcl 8.5+ and tcllib
  8. #
  9. # Wikipedia.org fetcher
  10. #
  11. # To enable you must .chanset #channel +wiki
  12. #
  13. # Tests: Whole number (list of possible interpretations)
  14. #
  15. package require http
  16. package require htmlparse
  17. package require tls
  18. ::http::register https 443 ::tls::socket
  19. namespace eval wiki {
  20. variable max_lines 1
  21. variable max_chars 400
  22. variable output_cmd "putserv"
  23. variable url "https://en.wikipedia.org/wiki/"
  24. bind pub -|- "!w" wiki::search
  25. bind pub -|- "!wiki" wiki::search
  26. # variable parse_regexp {(<table class.*?<p>.*?</p>.*?</table>)??.*?<p>(.*?)</p>\n<table id="toc"}
  27. variable parse_regexp {(?:</table>)?.*?<p>(.*)((</ul>)|(</p>)).*?((<table id="toc")|(<h2>)|(<table id="disambigbox"))}
  28. setudef flag wiki
  29. }
  30. proc wiki::fetch {term {url {}}} {
  31. if {$url != ""} {
  32. set token [http::geturl $url -timeout 10000]
  33. } else {
  34. set query [http::formatQuery [regsub -all -- {\s} $term "_"]]
  35. set token [http::geturl ${wiki::url}${query} -timeout 10000]
  36. }
  37. set data [http::data $token]
  38. set ncode [http::ncode $token]
  39. set meta [http::meta $token]
  40. upvar #0 $token state
  41. set fetched_url $state(url)
  42. http::cleanup $token
  43. # debug
  44. putlog "Fetch! term: $term url: $url fetched: $fetched_url"
  45. set fid [open "w-debug.txt" w]
  46. puts $fid $data
  47. close $fid
  48. # Follow redirects
  49. if {[regexp -- {^3\d{2}$} $ncode]} {
  50. return [wiki::fetch $term [dict get $meta Location]]
  51. }
  52. if {$ncode != 200} {
  53. error "HTTP query failed ($ncode): $data: $meta"
  54. }
  55. # If page returns list of results, choose the first one and fetch that
  56. #if {[regexp -- {<p>.*?((may refer to:)|(in one of the following senses:))</p>} $data]} {
  57. # regexp -- {<ul>.*?<li>.*? title="(.*?)">.*?</li>} $data -> new_query
  58. # return [wiki::fetch $new_query]
  59. #}
  60. if {![regexp -- $wiki::parse_regexp $data -> out]} {
  61. error "Parse error"
  62. }
  63. return [list url $fetched_url result [wiki::sanitise $out]]
  64. }
  65. proc wiki::sanitise {raw} {
  66. set raw [htmlparse::mapEscapes $raw]
  67. # Remove pronunciation stuff
  68. set raw [regsub -- {<span.*? class="IPA">.*?</span>} $raw ""]
  69. # Remove some help links
  70. set raw [regsub -- {<small class="metadata">.*?</small>} $raw ""]
  71. set raw [regsub -all -- {<(.*?)>} $raw ""]
  72. set raw [regsub -all -- {\[.*?\]} $raw ""]
  73. set raw [regsub -all -- {\n} $raw " "]
  74. return $raw
  75. }
  76. proc wiki::search {nick uhost hand chan argv} {
  77. if {![channel get $chan wiki]} { return }
  78. if {[string length $argv] == 0} {
  79. $wiki::output_cmd "PRIVMSG $chan :Please provide a term."
  80. return
  81. }
  82. set argv [string trim $argv]
  83. # Upper case first character
  84. set argv [string toupper [string index $argv 0]][string range $argv 1 end]
  85. if {[catch {wiki::fetch $argv} data]} {
  86. $wiki::output_cmd "PRIVMSG $chan :Error: $data"
  87. return
  88. }
  89. foreach line [wiki::split_line $wiki::max_chars [dict get $data result]] {
  90. if {[incr count] > $wiki::max_lines} {
  91. $wiki::output_cmd "PRIVMSG $chan :Output truncuated. [dict get $data url]"
  92. break
  93. }
  94. $wiki::output_cmd "PRIVMSG $chan :$line"
  95. }
  96. }
  97. # by fedex
  98. proc wiki::split_line {max str} {
  99. set last [expr {[string length $str] -1}]
  100. set start 0
  101. set end [expr {$max -1}]
  102. set lines []
  103. while {$start <= $last} {
  104. if {$last >= $end} {
  105. set end [string last { } $str $end]
  106. }
  107. lappend lines [string trim [string range $str $start $end]]
  108. set start $end
  109. set end [expr {$start + $max}]
  110. }
  111. return $lines
  112. }
  113. putlog "wiki.tcl loaded"