PageRenderTime 28ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/aigen.tcl

http://egghelp.googlecode.com/
TCL | 513 lines | 322 code | 105 blank | 86 comment | 61 complexity | 58f88693dbebb14d1307ea4cc7902e0e MD5 | raw file
  1. #----------------------------------------------------------------------------
  2. # aigen - ??????????? ???? (???????? ;)
  3. #----------------------------------------------------------------------------
  4. # ????????? ???????: .chanset #chan +aigen
  5. # ???????: !?????? <???>
  6. # !???? <???>
  7. # ?????: !???? <?????>
  8. # ???????: ???? ???? ?????? ?????? ??-??????! ;)
  9. package require Tcl 8.4
  10. package require http 2.5
  11. namespace eval aigen {
  12. foreach p [array names aigen *] { catch {unset aigen ($p) } }
  13. #----------------------------------------------------------------------------
  14. # ????????? ????????? ???????????? (Suzi / http.tcl)
  15. #----------------------------------------------------------------------------
  16. # ???????? ? ???????????? ???????, ??????, ???? ????????? ???????????
  17. variable author "anaesthesia"
  18. variable version "01.01"
  19. variable date "01-jun-2008"
  20. # ??? ?????????? ??? ??????? ?????????
  21. variable unamespace [namespace tail [namespace current]]
  22. # ??????? ??? ????????? ?????? (????? ???? ?????? ???????)
  23. variable pubprefix {!}
  24. variable pubflag {-|-}
  25. # pubcmd:???_??????????? "???????1 ???????2 ..."
  26. # ??????? ? ?? ????????? ????????, ?????? ? ??????? ???????? ????????? ????????
  27. variable pub:aigen "$unamespace monster ?????? dwarf ???? ????"
  28. # ???? ??? ? ????, ??? ????????? ??????
  29. variable msgprefix {!}
  30. variable msgflag {-|-}
  31. # ????? ?? ??????? ??? ??? ????????? ???????
  32. variable msg:aigen ${pub:aigen}
  33. # ????? ????????? ????????? ??? ????????? ???????, ?????? ? ???????? ??????? ?????? ??????
  34. # ??? ??????????????? ?????????? variable [pub|msg]:handler "string ..."
  35. # ????? ?????????????? ???????????? ??? ?????????? ????????
  36. # ???????? $unick, $uhost, $uchan
  37. # ??????? tcl ?????????, ??????????? ???????????? ?????????? id ???
  38. # ????????????? ???????.
  39. variable requserid {$uhost}
  40. # ???????????? ????? ????????? ?????????? ???????? ??? ?????? id
  41. variable maxreqperuser 1
  42. # ???????????? ????? ????????? ?????????? ????????
  43. variable maxrequests 5
  44. # ????? ????? ?????????, ? ??????? ??????? ?????? ?????????? ??? ?????????????,
  45. # ??????
  46. variable pause 30
  47. # ????? ??????-???????
  48. # ?????? ???? "proxyhost.dom:proxyport" ??? ?????? ??????, ???? ??????-??????
  49. # ?? ????????????
  50. variable proxy {}
  51. # ????????? ?????????? ?????, ???? ???????? "" -- ????? ???????????
  52. # ????????, ?? ???? ???? ???? ???? ?????????? ?? ?????? -- ?????? ????????
  53. # ???? "no" ???????? ???? ?????????? ????????? ??? ???? ????? ???????????
  54. # ???????? ? ?????? ?????????? ?? ?????? ????????? ?????? ???????
  55. # (??? ???? ?????? ???????? ?? ???? ???????, ??? ?? ??????????? ???? ????)
  56. variable flagactas ""
  57. # ??? ?????????? ?????, ????????? ??? ?????????/?????????? ??????? ?? ??????
  58. # ?? ????????? ??????????? ?? ?????? ?????? ????? ? ????? ??????????
  59. # ? ?????? ?????? ????? ?????? ???????????
  60. # ??? ????????? ?? ?????? ????????? ??????
  61. variable chflag "$flagactas$unamespace"
  62. setudef flag $chflag
  63. #----------------------------------------------------------------------------
  64. # ????????? ????????? ????????????
  65. #----------------------------------------------------------------------------
  66. # ????? ??? ???????? -- ?????? ?????? ??? ?? ???????
  67. # ????? ??????????????? ????? ? ???
  68. variable logrequests {'$unick', '$uhost', '$handle', '$uchan', '$ustr'}
  69. # ??????? ?????? ??? ?????????? ???????, ?? ????????? -- ?? ?????
  70. # ???????? $uchan & $unick
  71. variable pubsend {PRIVMSG $uchan :}
  72. # ??????? ?????? ??? ?????????? ???????, ?? ????????? -- ????????? ?????????
  73. # ???????? ?????? $unick ($uchan == $unick)
  74. variable msgsend {PRIVMSG $unick :}
  75. # ??????? ?????? ??? ??????/????????????? ???????
  76. # ???????? $unick
  77. variable errsend {NOTICE $unick :}
  78. # ???????????? ????? ?????????? ? ??????????? ????????
  79. variable maxredir 1
  80. # ??????? ??????? ? ?????????????, ?? ???? 30 ??????
  81. variable timeout 30000
  82. # ????????? ? ???????? ???????
  83. variable err_ok {}
  84. # ????????? ? ????????????? ???????? ??????, ??????? ? ??????? ?? ????????
  85. # ?????? ?????????? ? ????????????? ?? ????????
  86. variable err_fail {? ????????? ??? ?????? ?? ????????.}
  87. # ????????? ? ????????????? ??????? ????????
  88. variable err_queue_full {? ?????? ????? ??????? ??????? ????????? ? ?? ????? ????????? ??? ??????. ????????? ??????? ?????.}
  89. # ????????? ? ????????????? ??????? ??? ??????????? id
  90. variable err_queue_id {?????????? ????????? ????????? ?????????? ????????.}
  91. # ????????? ? ??? ??? ????? ????? ??????????????? ??????? ?? ???????
  92. # ???????? ?????????? $timewait -- ?????????? ?????, ?? ????????? ????????
  93. # ?????? ????? ????????
  94. variable err_queue_time {?????????? ????????? ??????? ?????. ?????? ????? ???????? ??? ????????????? ????? $timewait ???.}
  95. #----------------------------------------------------------------------------
  96. # ?????????? ?????????? ? ???
  97. #----------------------------------------------------------------------------
  98. # ?????, ? ???????? ?????????? ????????? ??????????
  99. variable fetchurl "http://aigenerators.net/"
  100. # ?????????? ????????? ???????????
  101. variable maxres 1
  102. # ??????? ????????
  103. variable reqqueue
  104. array unset reqqueue
  105. # ????????? ??????????
  106. variable laststamp
  107. array unset laststamp
  108. variable updinprogress 0
  109. variable updatetimeout 60000
  110. #---body---
  111. proc tolow {strr} {
  112. return [string tolower [string map {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} $strr]]
  113. }
  114. proc sspace {strr} {
  115. return [string trim [regsub -all {[\t\s]+} $strr { }]]
  116. }
  117. proc msg:aigen { unick uhost handle str } {
  118. pub:aigen $unick $uhost $handle $unick $str
  119. return
  120. }
  121. proc chkrusl {strr} {
  122. if {[lsearch -exact {? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?} $strr] > -1} {return 1} {return 0}
  123. }
  124. proc chkrus {strr} {
  125. set len [string length $strr]
  126. set cnt 0
  127. while {$cnt < $len} {
  128. if {[chkrusl [string index $strr $cnt]]} { return 1 }
  129. incr cnt
  130. }
  131. return 0
  132. }
  133. proc uenc {strr} {
  134. set str ""
  135. foreach byte [split [encoding convertto [encoding system] $strr] ""] {
  136. scan $byte %c i
  137. if {[string match {[%<>"]} $byte] || $i < 65 || $i > 122} {
  138. append str [format %%%02X $i]
  139. } else {
  140. append str $byte
  141. }
  142. }
  143. return [string map {%3A : %2D - %2E . %30 0 %31 1 %32 2 %33 3 %34 4 %35 5 %36 6 %37 7 %38 8 %39 9 \[ %5B \\ %5C \] %5D \^ %5E \_ %5F \` %60} $str]
  144. }
  145. proc pub:aigen { unick uhost handle uchan str } {
  146. variable requserid
  147. variable fetchurl
  148. variable mtype
  149. variable chflag
  150. variable flagactas
  151. variable errsend
  152. variable maxres
  153. variable pubprefix
  154. variable pubsend
  155. variable msgsend
  156. variable unamespace
  157. set id [subst -nocommands $requserid]
  158. set prefix [subst -nocommands $errsend]
  159. if { $unick ne $uchan } {
  160. if { ![channel get $uchan $chflag] ^ $flagactas eq "no" } {
  161. return
  162. }
  163. }
  164. set why [queue_isfreefor $id]
  165. if { $why != "" } {
  166. lput puthelp $why $prefix
  167. return
  168. }
  169. #---?????????
  170. set ustr [tolow $str]
  171. if {$ustr == ""} {
  172. if {$uchan eq $unick} {set prefix [subst -nocommands $msgsend]} {set prefix [subst -nocommands $pubsend]}
  173. lput puthelp "??????????? ????. \002??????\002: $pubprefix\?????? <???> \037???\037 $pubprefix\???? <???>" $prefix
  174. return
  175. } elseif {(![chkrus $ustr] || [string length $ustr] > 11) && ![string match "*????*" $::lastbind]} {
  176. lput puthelp "\037??? ?????? ???? ???????? ?????????? ? ???? ?? ??????? 11-? ????????\037." $prefix
  177. return
  178. } else {
  179. if {[string match "*????*" $::lastbind] || [string match "*dwarf*" $::lastbind]} {
  180. set ustr "dec_dwarf_pic.php?monster=[uenc $ustr]"
  181. set mtype 1
  182. } elseif {[string match "*????*" $::lastbind]} {
  183. set ustr "bayan.php?creo_text=[uenc $ustr]"
  184. set mtype 2
  185. } else {
  186. set ustr "dec_monster_pic1.php?monster=[uenc $ustr]"
  187. set mtype 0
  188. }
  189. }
  190. variable logrequests
  191. if { $logrequests ne "" } {
  192. set logstr [subst -nocommands $logrequests]
  193. variable unamespace
  194. lput putlog $logstr "$unamespace: "
  195. }
  196. ::http::config -useragent "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320)"
  197. variable fetchurl
  198. if { [queue_add "$fetchurl$ustr" $id "[namespace current]::dream:parser" [list $unick $uhost $uchan {}]] } {
  199. variable err_ok
  200. if { $err_ok ne "" } {
  201. lput puthelp "$err_ok." $prefix
  202. }
  203. } else {
  204. variable err_fail
  205. if { $err_fail ne "" } {
  206. lput puthelp $err_fail $prefix
  207. }
  208. }
  209. return
  210. }
  211. #---parser
  212. proc dream:parser { errid errstr body extra } {
  213. upvar $errid lerrid $errstr lerrstr $body lbody $extra lextra
  214. variable err_fail
  215. variable pubsend
  216. variable msgsend
  217. variable errsend
  218. variable useurl
  219. variable maxres
  220. variable mtype
  221. foreach { unick uhost uchan ustr } $lextra { break }
  222. if { $lerrid ne {ok} } {
  223. lput putserv [subst -nocommands $err_fail] [subst -nocommands $errsend]
  224. return
  225. }
  226. if { $uchan eq $unick } {
  227. set prefix [subst -nocommands $msgsend]
  228. } else {
  229. set prefix [subst -nocommands $pubsend]
  230. }
  231. #--suzi-patch
  232. global sp_version
  233. if {[info exists sp_version]} {
  234. set str [encoding convertfrom [encoding system] $lbody]
  235. } else {
  236. set str $lbody
  237. }
  238. #----------------------------------------------------------------------------
  239. ##---parser-specific------
  240. #----------------------------------------------------------------------------
  241. regsub -all "\n|\r|\t" $str {} str
  242. if {$mtype == 2} {
  243. if {[regexp {<table align=center><tr><th>(.*?)<br>} $str -> mhead]} {
  244. regsub -all -nocase -- "<b>|</b>" $mhead "\002" mhead
  245. regsub -all -- "<.*?>" $mhead {} mhead
  246. lput putserv "[sspace $mhead]" $prefix
  247. return
  248. } else {
  249. lput putserv "\037???????????? ????037." $prefix
  250. return
  251. }
  252. }
  253. if {[regexp {<tr><th>(.*?)</th></tr>.*?</td></tr><tr><td align=center>(.*?)<p><br><br></p>} $str -> mhead mdata]} {
  254. regsub -all -nocase -- "<b>|</b>" $mhead "\002" mhead
  255. regsub -all -nocase -- "<b>|</b>" $mdata "\002" mdata
  256. regsub -all -- "<.*?>" $mdata {} mdata
  257. if {$mtype} {
  258. lput putserv "[sspace $mhead]" $prefix
  259. } else {
  260. lput putserv "[sspace $mhead] :: [sspace $mdata]" $prefix
  261. }
  262. } else {
  263. lput putserv "\037????????? ?? ???????037." $prefix
  264. return
  265. }
  266. return
  267. }
  268. #----------------------------------------------------------------------------
  269. ##---ok------
  270. #----------------------------------------------------------------------------
  271. proc lput { cmd str { prefix {} } {maxchunk 420} } {
  272. set buf1 ""; set buf2 [list];
  273. foreach word [split $str] {
  274. append buf1 " " $word;
  275. if {[string length $buf1]-1 >= $maxchunk} {
  276. lappend buf2 [string range $buf1 1 end];
  277. set buf1 "";
  278. }
  279. }
  280. if {$buf1 != ""} {
  281. lappend buf2 [string range $buf1 1 end];
  282. }
  283. foreach line $buf2 {
  284. $cmd $prefix$line
  285. }
  286. return
  287. }
  288. #---queue
  289. proc queue_isfreefor { { id {} } } {
  290. variable reqqueue
  291. variable maxreqperuser
  292. variable maxrequests
  293. variable laststamp
  294. variable pause
  295. variable err_queue_full
  296. variable err_queue_id
  297. variable err_queue_time
  298. if { [info exists laststamp(stamp,$id)] } {
  299. set timewait [expr { $laststamp(stamp,$id) + $pause - [unixtime]}]
  300. if { $timewait > 0 } {
  301. return [subst -nocommands $err_queue_time]
  302. }
  303. }
  304. if { [llength [array names reqqueue -glob "*,$id"]] >= $maxreqperuser } {
  305. return $err_queue_id
  306. }
  307. if { [llength [array names reqqueue]] >= $maxrequests } {
  308. return $err_queue_full
  309. }
  310. return
  311. }
  312. #---add-to-queue
  313. proc queue_add { newurl id parser extra {redir 0} } {
  314. variable reqqueue
  315. variable proxy
  316. variable timeout
  317. variable laststamp
  318. ::http::config -proxyfilter "[namespace current]::queue_proxy"
  319. if { ! [catch {
  320. set token [::http::geturl $newurl -command "[namespace current]::queue_done" -binary true -timeout $timeout]
  321. } errid] } {
  322. set reqqueue($token,$id) [list $parser $extra $redir]
  323. set laststamp(stamp,$id) [unixtime]
  324. } else {
  325. return false
  326. }
  327. return true
  328. }
  329. #---proxy
  330. proc queue_proxy { url } {
  331. variable proxy
  332. if { $proxy ne {} } { return [split $proxy {:}] }
  333. return [list]
  334. }
  335. #---callback
  336. proc queue_done { token } {
  337. upvar #0 $token state
  338. variable reqqueue
  339. variable maxredir
  340. set errid [::http::status $token]
  341. set errstr [::http::error $token]
  342. set id [array names reqqueue "$token,*"]
  343. foreach { parser extra redir } $reqqueue($id) { break }
  344. regsub -- "^$token," $id {} id
  345. while (1) {
  346. if { $errid == "ok" && [::http::ncode $token] == 302 } {
  347. if { $redir < $maxredir } {
  348. array set meta $state(meta)
  349. if { [info exists meta(Location)] } {
  350. variable fetchurl
  351. queue_add "$fetchurl$meta(Location)" $id $parser $extra [incr redir]
  352. break
  353. }
  354. } else {
  355. set errid "error"
  356. set errstr "Maximum redirects reached"
  357. }
  358. }
  359. if { [catch { $parser {errid} {errstr} {state(body)} {extra} } errid ] } {
  360. lput putlog $errid "[namespace current] "
  361. }
  362. break
  363. }
  364. array unset reqqueue "$token,*"
  365. ::http::cleanup $token
  366. return
  367. }
  368. #---clear
  369. proc queue_clear_stamps {} {
  370. variable laststamp
  371. variable timeout
  372. variable timerID
  373. set curr [expr { [unixtime] - 2 * $timeout / 1000 }];
  374. foreach { id } [array names laststamp] {
  375. if { $laststamp($id) < $curr } {
  376. array unset laststamp $id;
  377. }
  378. }
  379. set timerID [timer 10 "[info level 0]"]
  380. }
  381. #---command aliases & bnd
  382. proc cmdaliases { { action {bind} } } {
  383. foreach { bindtype } {pub msg dcc} {
  384. foreach { bindproc } [info vars "[namespace current]::${bindtype}:*"] {
  385. variable "${bindtype}prefix"
  386. variable "${bindtype}flag"
  387. foreach { alias } [set $bindproc] {
  388. catch { $action $bindtype [set ${bindtype}flag] [set ${bindtype}prefix]$alias $bindproc }
  389. }
  390. }
  391. }
  392. return
  393. }
  394. #---killtimers
  395. if {[info exists timerID]} {
  396. catch {killtimer $timerID};
  397. catch {unset timerID}
  398. }
  399. #---rest
  400. [namespace current]::queue_clear_stamps
  401. cmdaliases
  402. global sp_version
  403. if {[info exists sp_version]} {
  404. putlog "[namespace current] v$version suzi_$sp_version \[$date\] by $author loaded."
  405. } else {
  406. putlog "[namespace current] v$version \[$date\] by $author loaded."
  407. }
  408. }