### # # Название: eweather2.tcl # Версия: 3.0 # Автор: tvrsh # Оффсайт: http://egghelp.ru/ # ### # # Описание: Скрипт "не простой" погоды с Яндекса. Теперь работает с базой(7700+) городов. Работает на боте _без_ Suzi патча. # В скрипте есть запоминался последнего посмотренного города при просмотре сегодняшней погоды. То-есть будет показываться погода # при команде без параметров. Как только вы посмотрите погоду на любой другой день кроме сегодняшнего, то запоминалка для вас # сбрасывается. # ### # # Установка: # 1. Скопируйте скрипт eweather2.tcl в папку scripts вашего бота. Базу городов ewbase.txt положите в корень бота. # 2. В файле eggdrop.conf впишите строку source scripts/eweather2.tcl # 3. Сделайте .rehash боту. # ### # # Версион хистори: # # 1.0(20.03.2010) Первая паблик версия. # 1.1(21.03.2010) + небольшой хелп по использованию # + погода в случайном городе # + небольшие изменения скрипта # 2.0(24.07.2010) Собрана база городов и скрипт переписан для работы с ней. # 2.1(26.07.2010) Запоминалка последнего города и показ погоды в нем при команде без параметров. # 2.2(12.08.2010) Погода на неделю если перед городом поставить +. # 2.3(12.08.2010) Исправлена ошибка с минусовой температурой на ботах с сузи. # 2.4(28.09.2010) Исправлена ошибка поиска "многословных" городов. # 19.11.2010 +сортировка найденных городов по алфавиту. # 2.5(17.12.2010) Переписан скрипт и база под новый формат запросов сайта. # + раскраска температуры (с) #eggdrop @ RusNet. # + много обновлений в оформлении. # 2.6(25.06.2011) Обновлена база городов. # + небольшие поправки в недельном и дневном выводах. # 2.7(29.11.2011) Добавлено локальное время, время и место обновления данных о погоде. # + обновлен вывод в канал всвязи с увеличением размера сообщения. # + короткие алиасы городов. # 2.8(19.02.2012) Скрипт обновлен после изменений на сайте. # 2.9(06.03.2012) Добавлен показа восхода/захода. # 3.0(09.06.2013) Обновил вывод и добавил показ вчерашней температуры. # ### # Объявляем пространство имен. namespace eval eweather {} # Сбрасываем значения всех переменных. foreach p [array names eweather *] { catch {unset eweather($p)} } # Указываем канальный флаг(.chanset #chan +eweather для включения скрипта). setudef flag eweather ### ### # Меню настроек ниже этой линии: # # ______________________________ # ### ### # Префикс команд. set eweather(pref) "!" # Бинды. set eweather(binds) "eweather ew пп п погода" # Файл базы городов. set eweather(base) "ewbase.txt" # Разрешить работу в привате? set eweather(msg) 1 # Краткие алиасы городов. set eweather(shortcuts_in) { "мск" "влд" "спб" } # Их полные названия. set eweather(shortcuts_out) { "Москва" "Владивосток" "Санкт-Петербург" } # Время перед повторным использованием команды. set eweather(delay) 5 # Юзерагент. set eweather(uagent) "Opera/9.80 (Windows NT 5.1; U; ru) Presto/2.10.229 Version/11.60" ### # Настройка цветов. # Цвет 1. set eweather(color1) \00314 # Цвет 2. set eweather(color2) \00303 # Цвет 3. set eweather(color3) \00305 ### ### ### # Ниже этой линии начинается код, не изменяйте его если не знаете TCL: # # ____________________________________________________________________ # ### ### # Версия скрипта. set eweather(version) "eweather2.tcl version 3.0" # Автор скрипта. set eweather(author) "tvrsh" package require http 2.7 # Обработка биндов. foreach bind [split $eweather(binds) " "] { bind pub -|- "$eweather(pref)$bind" ::eweather::eweather_pub if {$eweather(msg) >= 1} { bind msg -|- "$eweather(pref)$bind" ::eweather::eweather_msg } } # Процедура обработки приватных команд. proc ::eweather::eweather_msg {nick uhost hand text} { global eweather ::eweather::eweather_proc $nick $uhost $hand $nick $text } # Процедура обработки паблик команд. proc ::eweather::eweather_pub {nick uhost hand chan text} { global eweather # Проверяем наличие флага. if {![channel get $chan eweather]} { return 0 } ::eweather::eweather_proc $nick $uhost $hand $chan $text } # Процедура обработки запроса. proc ::eweather::eweather_proc {nick uhost hand chan text} { global eweather lastbind if {[info exists eweather(lasttime,$chan)] && [expr $eweather(lasttime,$chan) + $eweather(delay)] > [clock seconds]} { putserv "NOTICE $nick :$eweather(color1)Запрос не чаще одного раза в $eweather(color2)$eweather(delay) $eweather(color1)[lindex {. секунду секунды секунд} [eweather_numgrp $eweather(delay)]].\003" putserv "NOTICE $nick :$eweather(color1)Подождите $eweather(color3)[expr $eweather(delay) - [expr [clock seconds] - $eweather(lasttime,$chan)]] $eweather(color1)[lindex {. секунду секунды секунд} [eweather_numgrp [expr $eweather(delay) - [expr [clock seconds] - $eweather(lasttime,$chan)]]]] до следующего запроса.\003" return 0 } set eweather(start) [clock clicks] if {[llength [split $text]] < 1} { if {[info exists eweather(nickbase)]} { foreach line $eweather(nickbase) { if {[lindex [split $line "@"] 0] == $nick} { set query [lindex [split $line "@"] 1] ::eweather::eweather_parce $nick $uhost $hand $chan $query return 0 } } } putserv "PRIVMSG $chan :$eweather(color1)Используйте $eweather(color2)\002$lastbind город\002 $eweather(color1)для погоды сейчас или $eweather(color2)\002$lastbind город +1\002 $eweather(color1)для погода на завтра, $eweather(color2)\002+2\002 $eweather(color1)на послезавтра и так далее. Если по вашему запросу найдено несколько городов, то вторым параметром через дефис($eweather(color2)\002-\002$eweather(color1)) укажите номер города в списке найденных.\003" putserv "PRIVMSG $chan :$eweather(color1)Например: $eweather(color2)\002$lastbind под -3 +1\002 $eweather(color1)- покажет погоду в городе Подольск на завтра.\003" return 0 } set text [::eweather::en2ru $text] regsub -all -nocase -- {\s+} $text " " text catch { unset eweather(showweek) } if {[string index [join [lindex [split $text] 0]] 0] == "+"} { set eweather(showweek) 1 set text [string replace [join [split $text]] 0 0] } if {[string match -nocase "*\ -*" $text]} { set cit [lindex [split $text " -"] 0] } else { if {[string match -nocase "*\ +*" $text]} { set cit [lindex [split $text " +"] 0] } else { set cit $text } } set num [lsearch -nocase "$eweather(shortcuts_in)" "$cit"] if {$num > -1} { set cit [lindex $eweather(shortcuts_out) $num] } catch {set fid [open $eweather(base) "r"]} error if {[string match -nocase "*couldn't open*" $error]} { putserv "PRIVMSG $chan :$eweather(color1)Ошибка: $eweather(color3)$error$eweather(color1).\003" return 0 } fconfigure $fid -encoding cp1251 foreach city [split [read $fid] "\n"] { if {$city != ""} { if {[string match -nocase "$cit" [lindex [regexp -inline -- {^(.*?)\s\(.*?\)} [join [lindex [split $city "|"] 1]]] 1]]} { lappend citys "$city+" } } } close $fid if {![info exists citys]} { putserv "PRIVMSG $chan :$eweather(color1)По вашему запросу $eweather(color2)\"$cit\" $eweather(color1)не найден ни один город.\003" return 0 } else { foreach elem $citys { lappend list2 [lindex [split $elem "|"] 1]|[lindex [split $elem "|"] 0] } foreach elem [lsort $list2] { lappend list3 [lindex [split $elem "|"] 1]|[lindex [split $elem "|"] 0] } set citys $list3 set query [lindex $citys 0] regexp -- {.*? \((.*?)\)\+} [lindex [split [lindex $citys 0] "|"] 1] "" eweather(country) if {[llength $citys] > 1} { foreach fcity [split $citys "+"] { if {[lindex [split $fcity "|"] 1] != ""} { lappend fcitys [lindex [split $fcity "|"] 1] } } if {[llength $citys] <= 5} { putserv "PRIVMSG $chan :$eweather(color1)По вашему запросу $eweather(color2)\"$cit\" $eweather(color1)найдено $eweather(color2)[llength $citys] $eweather(color1)[lindex {. город города городов} [eweather_numgrp [llength $citys]]]: $eweather(color2)[string trimright [join [lsort $fcitys] "$eweather(color1), $eweather(color2)"] "$eweather(color1), $eweather(color2)"]$eweather(color1).\003" } else { putserv "PRIVMSG $chan :$eweather(color1)По вашему запросу $eweather(color2)\"$cit\" $eweather(color1)найдено $eweather(color2)[llength $citys] $eweather(color1)[lindex {. город города городов} [eweather_numgrp [llength $citys]]]. Первые 5 найденных: $eweather(color2)[string trimright [join [lrange [lsort $fcitys] 0 4] "$eweather(color1), $eweather(color2)"] "$eweather(color1), $eweather(color2)"]$eweather(color1).\003" } } } catch { unset eweather(showday) } if {[string match -nocase "*\ -*" $text]} { set text_ -[lindex [split $text "-"] 1] } else { if {[string match -nocase "*\ +*" $text]} { set text_ +[lindex [split $text "+"] 1] } else { set text_ $text } } if {$text_ != "" && [llength $citys] >= 1} { regexp -- {\-(.*?)$} $text_ "" citnr if {[string index $text_ 0] == "-" && $citnr <= [llength $citys] && $citnr > 0} { set query [lindex $citys [expr $citnr - 1]] regexp -- {.*? \((.*?)\)\+} [lindex [split [lindex $citys [expr $citnr - 1]] "|"] 1] "" eweather(country) set text__ [lindex [split $text_] 1] if {$text__ != ""} { if {[string index $text__ 0] == "+" && [string index $text__ 1] < 10 && [string index $text__ 1] > 0} { set eweather(showday) [string index $text__ 1] } else { catch { unset eweather(showday) } } } } else { set text__ +[lindex [split $text_ "+"] 1] if {$text__ != ""} { if {[string index $text__ 0] == "+" && [string index $text__ 1] < 10 && [string index $text__ 1] > 0} { set eweather(showday) [string index $text__ 1] } else { catch { unset eweather(showday) } } } } } ::eweather::eweather_parce $nick $uhost $hand $chan $query } # Процедура парсинга информации о погоде. proc ::eweather::eweather_parce {nick uhost hand chan query} { global eweather lastbind putlog "\[eweather\] $nick/$chan[lindex [split $query "|"] 0]" ::http::config -useragent $eweather(uagent) catch {set eweather_tok [::http::geturl "http://pogoda.yandex.ru[lindex [split $query "|"] 0]" -timeout "15000"]} error if {[string match -nocase "*couldn't open socket*" $error]} { putserv "PRIVMSG $chan :$eweather(color1)Ошибка: $eweather(color3)Сouldn't open socket$eweather(color1). Адрес $eweather(color2)\"http://pogoda.yandex.ru/$query/\" $eweather(color1)не существует.\003" return 0 } if {[::http::status $eweather_tok] == "timeout"} { putserv "PRIVMSG $chan :$eweather(color1)Ошибка: $eweather(color3)Сonnect timeout$eweather(color1). Проверьте скорость соединения своего бота.\003" return 0 } set data [::http::data $eweather_tok] ::http::cleanup $eweather_tok if {![info exists ::sp_version]} { set data [encoding convertto utf-8 [encoding convertfrom cp1251 $data]] } # if {[info exists ::sp_version]} { # set data [encoding convertfrom utf-8 $data] # } else { # set data [encoding convertto cp1251 [encoding convertfrom utf-8 $data]] # } set wmsg [list] # Получаем город. regexp {
} $data "" wcity # Получаем погоду сейчас. regexp {