= WeeChat водич за скриптовање :author: Sébastien Helleu :email: flashcode@flashtux.org :lang: sr :toc-title: Садржај Превод: * Иван Пешић (), 2021. Ово упутство описује WeeChat чет клијент и део је програма WeeChat. Последња верзија овог документа се налази на https://weechat.org/doc/[овој страници ^↗^^]. [[introduction]] == Увод WeeChat (Wee Enhanced Environment for Chat) је бесплатни чет клијент, једноставан и брз, дизајниран за многе оперативне системе. Ово упутство документује начин писања скрипти за програм WeeChat употребом једног од подржаних скрипт језика: * Python * Perl * Ruby * Lua * Tcl * Guile (Scheme) * JavaScript * PHP [NOTE] Almost all examples in this doc are written in Python, but API is the same for other languages. [[scripts_in_weechat]] == Скрипте у програму WeeChat [[weechat_architecture]] === Архитектура програма WeeChat Програм WeeChat се извршава у једној нити, па се то применњује и на скрипте. Кôд скрипте се извршава: * када се скрипта учита: типично позивом <> * када програм WeeChat позове функцију повратног позива куке (погледајте поглавље <>). Док се кôд скрипте извршава, програм WeeChat чека на крај извршавања пре него што настави. Тако да скрипте *НЕ СМЕЈУ* да извршавају блокирајуће операције као што су мрежни позиви без употребе одређених API функција као што је `+hook_process+`. [IMPORTANT] Скрипта *НИКАДА* не сме да се рачва или да креира нити без употребе одговарајуће API функције, то може да сруши програм WeeChat. + Ако нешто мора да се извршава у позадини, употребите функцију `+hook_process+`. Погледајте пример у поглављу <> као и документацију функције `+hook_process+` у link:weechat_plugin_api.sr.html#_hook_process[WeeChat референтном приручнику API додатака ^↗^^]. [[languages_specificities]] === Језичке специфичности [[language_python]] ==== Python [[python_module]] ===== Модул Програм WeeChat дефинише `weechat` модул који мора да се увезе командом `import weechat`. + Python стаб за WeeChat API је соступан у репозиторијуму: https://raw.githubusercontent.com/weechat/weechat/master/src/plugins/python/weechat.pyi[weechat.pyi ^↗^^]. [[python_functions]] ===== Функције Функције се позивају са `+weechat.xxx(арг1, арг2, ...)+`. Функције `+print*+` се у језику python зову `+prnt*+` (јер је `print` била резервисана реч у Python 2). [[python_strings]] ===== Стрингови који се примају у функцијама повратног позива У Python 3 и у програму WeeChat верзије ≥ 2.7, стрингови који се примају у функцијама повратног позива имају тип `str` ако стринг садржи важеће UTF-8 податке (што је најчешћи случај), или `bytes` ако стринг није важећи UTF-8. Тако да би функција повратног позива морала да води рачуна о овом типу у случају да је могућ пријем неважећег UTF-8 садржаја. Неважећи UTF-8 подаци могу да се приме у следећим случајевима, тако да функције повратног позива могу да приме стринг типа `str` или `bytes` (ова листа није потпуна): [width="100%", cols="3m,3m,3m,8", options="header"] |=== | API фунцкија | Аргументи | Примери | Опис | hook_modifier | irc_in_yyy | pass:[irc_in_privmsg] + pass:[irc_in_notice] | Порука која се прими у IRC додатку, пре него што се декодира у UTF-8 (користи се интерно). + + Препоручује се да се уместо ње користи модификатор `+irc_in2_yyy+`, примљени стринг је увек валидан UTF-8. + Погледајте функцију `+hook_modifier+` у link:weechat_plugin_api.sr.html#_hook_modifier[WeeChat референтном приручнику API додатака ^↗^^]. | hook_signal | xxx,irc_out_yyy + xxx,irc_outtags_yyy | pass:[*,irc_out_privmsg] + pass:[*,irc_out_notice] + pass:[*,irc_outtags_privmsg] + pass:[*,irc_outtags_notice] | Порука коју шаље IRC додатак, након што се кодира у `encode` скуп карактера који је дефинисао корисник (у случају да се разликује од подразумеваног `UTF-8`). + + Препоручује се да се уместо њега користи сигнал `+xxx,irc_out1_yyy+`, стринг који се прима је увек валидан UTF-8. + Погледајте функцију `+hook_signal+` у link:weechat_plugin_api.sr.html#_hook_signal[WeeChat референтном приручнику API додатака ^↗^^]. | hook_process + hook_process_hashtable | - | - | Излаз команде који се шаље функцији повратног позива може да садржи неважеће UTF-8 податке. |=== [[language_perl]] ==== Perl [[perl_functions]] ===== Функције Функције се позивају са `+weechat::xxx(арг1, арг2, ...);+`. [[language_ruby]] ==== Ruby [[ruby_init]] ===== Иницијализација Морате да дефинишете _weechat_init_ и да у њој позовете _register_. [[ruby_functions]] ===== Функције Функције се позивају са `+Weechat.xxx(арг1, арг2, ...)+`. Услед ограничења језика Ruby (функција може да има максимално 15 аргумената), функција `+Weechat.config_new_option+` прихвата функције повратног позива у низу од 6 стрингова (3 повратна позива + 3 стринга са подацима), тако да позив ове функције изгледа овако: [source,ruby] ---- Weechat.config_new_option(config, section, "name", "string", "description of option", "", 0, 0, "value", "value", 0, ["check_cb", "", "change_cb", "", "delete_cb", ""]) ---- И функција `+Weechat.bar_new+` прима боје у низу од 4 стринга (color_fg, color_delim, color_bg, color_bg_inactive), тако да позив ове функције изгледа овако: [source,ruby] ---- Weechat.bar_new("name", "off", "0", "window", "", "left", "vertical", "vertical", "0", "0", ["default", "default", "default", "default"], "0", "items") ---- [[language_lua]] ==== Lua [[lua_functions]] ===== Функције Функције се позивају са `+weechat.xxx(арг1, арг2, ...)+`. [[language_tcl]] ==== Tcl [[tcl_functions]] ===== Функције Функције се позивају са `+weechat::xxx арг1 арг2 ...+`. [[tcl_null]] ===== Null вредности Пошто Tcl има само стринг типове, не постоји могућност да се проследи аргумент null типа када функција прихвата null вредности или да прихвати као аргумент у функцији повратног позива. Да би се решио овај проблем WeeChat API дефинише константу `$::weechat::WEECHAT_NULL` која има улогу null вредности. Ова константа се дефинипе као `\uFFFF\uFFFF\uFFFFWEECHAT_NULL\uFFFF\uFFFF\uFFFF`, тако да је мала вероватноћа да се појави без намере. Ову константу можете да проследите када функција као аргумент прихвата null и вретиће вам се као вредност аргумента у функцији повратног позива ако је вредност аргумента null. Да бисте видели које функције прихватају null вредности и прослеђују null вредности функцијама повратног позива, погледајте Python прототипе у link:weechat_plugin_api.en.html[API референтном приручнику WeeChat додатака ^↗^^]. [[language_guile]] ==== Guile (Scheme) [[guile_functions]] ===== Функције Функције се позивају са `+(weechat:xxx арг1 арг2 ...)+`. Следеће функције узимају једну листу аргумената (уместо више аргумената као код осталих функција), јер број аргумената прелази дозвољен максимални број аргумената у језику Guile: * config_new_section * config_new_option * bar_new [[language_javascript]] ==== JavaScript [[javascript_functions]] ===== Функције Функције се позивају са `+weechat.xxx(арг1, арг2, ...);+`. [[language_php]] ==== PHP [[php_functions]] ===== Функције Функције се позивају са `+weechat_xxx(арг1, арг2, ...);+`. [[register_function]] === Функција за регистрацију Све WeeChat скрипте морају да се „пријаве” програму WeeChat, и то мора да буде прва WeeChat функција која се позива у скрипти. Прототип (Python): [source,python] ---- def register(name: str, author: str, version: str, license: str, description: str, shutdown_function: str, charset: str) -> int: ... ---- Аргументи: * _име_: стринг, интерно име скрипте * _аутор_: стринг, име аутора * _верзија_: стринг, верзија скрипте * _лиценца_: стринг, лиценца скрипте * _опис_: стринг, кратак опис скрипте * _искључ_функција_: стринг, име функције која се позива када се скрипте уклања из меморије (може бити и празан стринг) * _скуп_кар_: стринг, скуп карактера скрипте (ако је ваша скрипта UTF-8, овде можете да користите празну вредности, јер је UTF-8 подразумевани скуп карактера) Пример скрипте, за сваки језик: * Python: [source,python] ---- import weechat weechat.register("test_python", "FlashCode", "1.0", "GPL3", "Test script", "", "") weechat.prnt("", "Поздрав од python скрипте!") ---- * Perl: [source,perl] ---- weechat::register("test_perl", "FlashCode", "1.0", "GPL3", "Test script", "", ""); weechat::print("", "Поздрав од perl скрипте!"); ---- * Ruby: [source,ruby] ---- def weechat_init Weechat.register("test_ruby", "FlashCode", "1.0", "GPL3", "Test script", "", "") Weechat.print("", "Поздрав од ruby скрипте!") return Weechat::WEECHAT_RC_OK end ---- * Lua: [source,lua] ---- weechat.register("test_lua", "FlashCode", "1.0", "GPL3", "Test script", "", "") weechat.print("", "Поздрав од lua скрипте!") ---- * Tcl: [source,tcl] ---- weechat::register "test_tcl" "FlashCode" "1.0" "GPL3" "Test script" "" "" weechat::print "" "Поздрав од tcl скрипте!" ---- * Guile (Scheme): [source,lisp] ---- (weechat:register "test_scheme" "FlashCode" "1.0" "GPL3" "Test script" "" "") (weechat:print "" "Поздрав од scheme скрипте!") ---- * JavaScript: [source,javascript] ---- weechat.register("test_js", "FlashCode", "1.0", "GPL3", "Test script", "", ""); weechat.print("", "Поздрав од javascript скрипте!"); ---- * PHP: [source,php] ---- weechat_register('test_php', 'FlashCode', '1.0', 'GPL3', 'Test script', '', ''); weechat_print('', 'Поздрав од PHP скрипте!'); ---- [[load_script]] === Учитавање скрипте За учитавање скрипти се препоручује употреба додатка „script”, на пример: ---- /script load script.py /script load script.pl /script load script.rb /script load script.lua /script load script.tcl /script load script.scm /script load script.js /script load script.php ---- Сваки језик има и своју команду: ---- /python load script.py /perl load script.pl /ruby load script.rb /lua load script.lua /tcl load script.tcl /guile load script.scm /javascript load script.js /php load script.php ---- Можете направити линк у директоријуму _language/autoload_ ако желите да се скрипта аутоматски учитава када се програм WeeChat покреће. На пример, са језиком Python: ---- $ cd ~/.local/share/weechat/python/autoload $ ln -s ../script.py ---- [NOTE] Када се скрипта инсталира командом `/script install`, линк у _autoload_ директоријуму се аутоматски креира. [[differences_with_c_api]] == Разлике у односу на C API API скриптовања је скоро у потпуности исти као и API C додатака. Можете да погледате следећи линк: weechat_plugin_api.sr.html[WeeChat референца API додатака] у вези детаља сваке функције у API: прототип, аргументи, повратне вредности, примери. Важно је да се направи разлика између _додатка_ и _скрипте_: _додатак_ је бинарни фајл који се компајлира и учитава командом `/plugin`, док је _скрипта_ текст фајл који се учитава додатком као што је _python_ командом `/python`. Када ваша скрипта _test.py_ позива WeeChat API функцију, путања је оваква: .... ┌──────────────────────┐ ╔══════════════════╗ │ python додатак │ ║ WeeChat „језгро” ║ ├────────────┬─────────┤ ╟─────────┐ ║ test.py ─────► │ script API │ C API │ ─────► ║ C API │ ║ └────────────┴─────────┘ ╚═════════╧════════╝ .... Када WeeChat позове функцију повратног позива у вашој скрипти _test.py_, путања бити обрнута у односу на претходну путању: .... ╔══════════════════╗ ┌──────────────────────┐ ║ WeeChat „језгро” ║ │ python додатак │ ║ ┌─────────╢ ├─────────┬────────────┤ ║ │ C API ║ ─────► │ C API │ script API │ ─────► test.py ╚════════╧═════════╝ └─────────┴────────────┘ .... [[pointers]] === Показивачи Као што вероватно већ знате, у скриптама нема правих „показивача”. Тако да када API функције врате показивач, он се за потребе скрипте конвертује у стринг. На пример, ако функција врати показивач 0x1234ab56, скрипта ће примити стринг „0x1234ab56”. А када API функција очекује показивач у аргументима, скрипта мора да проследи ту стринг вредност. C додатак ће да га конвертује у реални показивач пре него што позове C API функцију. Дозвољени су празни стрингови или „0x0”. На пример, ако желите да испишете податке у бафер језгра (главни WeeChat бафер), можете урадити следеће: [source,python] ---- weechat.prnt("", "здраво!") ---- [WARNING] Из разлога брзине, програм WeeChat у многим функцијама не проверава исправност вашег показивача. Ваш посао је да проверите да ли прослеђујете важећи показивач, у супротном бисте могли видети фин извештај о краху ;) [[callbacks]] === Функције повратног позива Скоро све WeeChat функције повратног позива морају да врате WEECHAT_RC_OK или WEECHAT_RC_ERROR (изузетак од овог правила је функција повратног позива модификатора, она враћа стринг). C функције повратног позива користе „callback_pointer” и „callback_data” аргументе, и то су показивачи. У API скриптовања постоји само „callback_data” (или „data”), и то је стринг, а не показивач. Пример функције повратног позива, за сваки језик: * Python: [source,python] ---- def timer_cb(data, remaining_calls): weechat.prnt("", "timer! data=%s" % data) return weechat.WEECHAT_RC_OK weechat.hook_timer(1000, 0, 1, "timer_cb", "test") ---- * Perl: [source,perl] ---- sub timer_cb { my ($data, $remaining_calls) = @_; weechat::print("", "timer! data=$data"); return weechat::WEECHAT_RC_OK; } weechat::hook_timer(1000, 0, 1, "timer_cb", "test"); ---- * Ruby: [source,ruby] ---- def timer_cb(data, remaining_calls) Weechat.print("", "timer! data=#{data}"); return Weechat::WEECHAT_RC_OK end Weechat.hook_timer(1000, 0, 1, "timer_cb", "test"); ---- * Lua: [source,lua] ---- function timer_cb(data, remaining_calls) weechat.print("", "timer! data="..data) return weechat.WEECHAT_RC_OK end weechat.hook_timer(1000, 0, 1, "timer_cb", "test") ---- * Tcl: [source,tcl] ---- proc timer_cb { data remaining_calls } { weechat::print {} "timer! data=$data" return $::weechat::WEECHAT_RC_OK } weechat::hook_timer 1000 0 1 timer_cb test ---- * Guile (Scheme): [source,lisp] ---- (define (timer_cb data remaining_calls) (weechat:print "" (string-append "timer! data=" data)) weechat:WEECHAT_RC_OK ) (weechat:hook_timer 1000 0 1 "timer_cb" "test") ---- * JavaScript: [source,javascript] ---- function timer_cb(data, remaining_calls) { weechat.print("", "timer! data=" + data); return weechat.WEECHAT_RC_OK; } weechat.hook_timer(1000, 0, 1, "timer_cb", "test"); ---- * PHP: [source,php] ---- $timer_cb = function ($data, $remaining_calls) { weechat_print('', 'timer! data=' . $data); return WEECHAT_RC_OK; }; weechat_hook_timer(1000, 0, 1, $timer_cb, 'test'); ---- [[script_api]] == API скриптовања За више информација о функцијама које постоје у API, молимо вас да прочитате link:weechat_plugin_api.sr.html[WeeChat референтни приручник API додатака ^↗^^]. [[script_api_functions]] === Функције Листа функција у API скриптовања: [width="100%", cols="1,5", options="header"] |=== | Категорија | Функције | опште | register | додаци | plugin_get_name | стрингови | charset_set + iconv_to_internal + iconv_from_internal + gettext + ngettext + strlen_screen + string_match + string_match_list + string_has_highlight + string_has_highlight_regex + string_mask_to_regex + string_format_size + string_parse_size + string_color_code_size + string_remove_color + string_is_command_char + string_input_for_buffer + string_eval_expression + string_eval_path_home | директоријуми | mkdir_home + mkdir + mkdir_parents | сортиране листе | list_new + list_add + list_search + list_search_pos + list_casesearch + list_casesearch_pos + list_get + list_set + list_next + list_prev + list_string + list_size + list_remove + list_remove_all + list_free | кофнигурациони фајлови | config_new + config_new_section + config_search_section + config_new_option + config_search_option + config_string_to_boolean + config_option_reset + config_option_set + config_option_set_null + config_option_unset + config_option_rename + config_option_is_null + config_option_default_is_null + config_boolean + config_boolean_default + config_integer + config_integer_default + config_string + config_string_default + config_color + config_color_default + config_write_option + config_write_line + config_write + config_read + config_reload + config_option_free + config_section_free_options + config_section_free + config_free + config_get + config_get_plugin + config_is_set_plugin + config_set_plugin + config_set_desc_plugin + config_unset_plugin | тастерске пречице | key_bind + key_unbind | приказ | prefix + color + print (за python: prnt) + print_date_tags (за python: prnt_date_tags) + print_y (за python: prnt_y) + print_y_date_tags (за python: prnt_y_date_tags) + log_print | куке | hook_command + hook_command_run + hook_timer + hook_fd + hook_process + hook_process_hashtable + hook_connect + hook_line + hook_print + hook_signal + hook_signal_send + hook_hsignal + hook_hsignal_send + hook_config + hook_completion + hook_modifier + hook_modifier_exec + hook_info + hook_info_hashtable + hook_infolist + hook_focus + hook_set + unhook + unhook_all | бафери | buffer_new + buffer_new_props + current_buffer + buffer_search + buffer_search_main + buffer_clear + buffer_close + buffer_merge + buffer_unmerge + buffer_get_integer + buffer_get_string + buffer_get_pointer + buffer_set + buffer_string_replace_local_var + buffer_match_list | прозори | current_window + window_search_with_buffer + window_get_integer + window_get_string + window_get_pointer + window_set_title | листа надимака | nicklist_add_group + nicklist_search_group + nicklist_add_nick + nicklist_search_nick + nicklist_remove_group + nicklist_remove_nick + nicklist_remove_all + nicklist_group_get_integer + nicklist_group_get_string + nicklist_group_get_pointer + nicklist_group_set + nicklist_nick_get_integer + nicklist_nick_get_string + nicklist_nick_get_pointer + nicklist_nick_set | траке | bar_item_search + bar_item_new + bar_item_update + bar_item_remove + bar_search + bar_new + bar_set + bar_update + bar_remove | команде | command + command_options | довршавање | completion_new + completion_search + completion_get_string + completion_list_add + completion_free | infos | info_get + info_get_hashtable | infolists | infolist_new + infolist_new_item + infolist_new_var_integer + infolist_new_var_string + infolist_new_var_pointer + infolist_new_var_time + infolist_get + infolist_next + infolist_prev + infolist_reset_item_cursor + infolist_search_var + infolist_fields + infolist_integer + infolist_string + infolist_pointer + infolist_time + infolist_free | hdata | hdata_get + hdata_get_var_offset + hdata_get_var_type_string + hdata_get_var_array_size + hdata_get_var_array_size_string + hdata_get_var_hdata + hdata_get_list + hdata_check_pointer + hdata_move + hdata_search + hdata_char + hdata_integer + hdata_long + hdata_string + hdata_pointer + hdata_time + hdata_hashtable + hdata_compare + hdata_update + hdata_get_string | ажурирање | upgrade_new + upgrade_write_object + upgrade_read + upgrade_close |=== [[script_api_constants]] === Константе Листа константи у API скриптовања: [width="100%", cols="1,5", options="header"] |=== | Категорија | Константе | повратни кодови | `WEECHAT_RC_OK` (цео број) + `WEECHAT_RC_OK_EAT` (цео број) + `WEECHAT_RC_ERROR` (цео број) | конфигурациони фајлови | `WEECHAT_CONFIG_READ_OK` (цео број) + `WEECHAT_CONFIG_READ_MEMORY_ERROR` (цео број) + `WEECHAT_CONFIG_READ_FILE_NOT_FOUND` (цео број) + `WEECHAT_CONFIG_WRITE_OK` (цео број) + `WEECHAT_CONFIG_WRITE_ERROR` (цео број) + `WEECHAT_CONFIG_WRITE_MEMORY_ERROR` (цео број) + `WEECHAT_CONFIG_OPTION_SET_OK_CHANGED` (цео број) + `WEECHAT_CONFIG_OPTION_SET_OK_SAME_VALUE` (цео број) + `WEECHAT_CONFIG_OPTION_SET_ERROR` (цео број) + `WEECHAT_CONFIG_OPTION_SET_OPTION_NOT_FOUND` (цео број) + `WEECHAT_CONFIG_OPTION_UNSET_OK_NO_RESET` (цео број) + `WEECHAT_CONFIG_OPTION_UNSET_OK_RESET` (цео број) + `WEECHAT_CONFIG_OPTION_UNSET_OK_REMOVED` (цео број) + `WEECHAT_CONFIG_OPTION_UNSET_ERROR` (цео број) | сортиране листе | `WEECHAT_LIST_POS_SORT` (стринг) + `WEECHAT_LIST_POS_BEGINNING` (стринг) + `WEECHAT_LIST_POS_END` (стринг) | врућа листа | `WEECHAT_HOTLIST_LOW` (стринг) + `WEECHAT_HOTLIST_MESSAGE` (стринг) + `WEECHAT_HOTLIST_PRIVATE` (стринг) + `WEECHAT_HOTLIST_HIGHLIGHT` (стринг) | кука process | `WEECHAT_HOOK_PROCESS_RUNNING` (цео број) + `WEECHAT_HOOK_PROCESS_ERROR` (цео број) | кука connect | `WEECHAT_HOOK_CONNECT_OK` (цео број) + `WEECHAT_HOOK_CONNECT_ADDRESS_NOT_FOUND` (цео број) + `WEECHAT_HOOK_CONNECT_IP_ADDRESS_NOT_FOUND` (цео број) + `WEECHAT_HOOK_CONNECT_CONNECTION_REFUSED` (цео број) + `WEECHAT_HOOK_CONNECT_PROXY_ERROR` (цео број) + `WEECHAT_HOOK_CONNECT_LOCAL_HOSTNAME_ERROR` (цео број) + `WEECHAT_HOOK_CONNECT_GNUTLS_INIT_ERROR` (цео број) + `WEECHAT_HOOK_CONNECT_GNUTLS_HANDSHAKE_ERROR` (цео број) + `WEECHAT_HOOK_CONNECT_MEMORY_ERROR` (цео број) + `WEECHAT_HOOK_CONNECT_TIMEOUT` (цео број) + `WEECHAT_HOOK_CONNECT_SOCKET_ERROR` (цео број) | кука signal | `WEECHAT_HOOK_SIGNAL_STRING` (стринг) + `WEECHAT_HOOK_SIGNAL_INT` (стринг) + `WEECHAT_HOOK_SIGNAL_POINTER` (стринг) |=== [[common_tasks]] == Уобичајени задаци Ово поглавље приказује неке уобичајене задатке, уз примере. Овде се користе само делимичне ствари из API, за потпуно упутство, погледајте link:weechat_plugin_api.sr.html[WeeChat референтни приручник API додатака ^↗^^]. [[buffers]] === Бафери [[buffers_display_messages]] ==== Приказ порука Празан стринг се често користи за рад са WeeChat бафером језгра. За остале бафере, морате навести показивач (као стринг, погледајте <>). Примери: [source,python] ---- # приказ „здраво” у баферу језгра weechat.prnt("", "здраво") # приказ „здраво” у баферу језгра, али без уписа у лог фајл # (само у верзијама ≥ 0.3.3) weechat.prnt_date_tags("", 0, "no_log", "здраво") # приказ префикса „==>” и поруке „здраво” у текућем баферу # (префикс и порука су раздвојени таб карактером) weechat.prnt(weechat.current_buffer(), "==>\tздраво") # приказ поруке о грешки у баферу језгра (са префиксом грешка) weechat.prnt("", "%sпогрешни аргументи" % weechat.prefix("грешка")) # приказ поруке са бојом у баферу језгра weechat.prnt("", "текст %sжуто на плавом" % weechat.color("yellow,blue")) # претрага бафера и приказ поруке # (пуно име бафера је додатак.име, на пример: „irc.libera.#weechat”) buffer = weechat.buffer_search("irc", "libera.#weechat") weechat.prnt(buffer, "порука на #weechat каналу") # још једно решење за проналажење IRC бафера (боље) # (приметите да су сервер и канал раздвојени запетом) buffer = weechat.info_get("irc_buffer", "libera,#weechat") weechat.prnt(buffer, "порука на #weechat каналу") ---- [NOTE] Print функција се назива `prnt` у Python, а `print` у осталим језицима. [[buffers_send_text]] ==== Слање текста у бафер Текст или команду можете да пошаљете у бафер. Ово је потпуно исто као да откуцате текст на командној линији и притиснете [Ентер]. Примери: [source,python] ---- # извршавање команде „/help” у текућем баферу (резултат иде у бафер језгра) weechat.command("", "/help") # слање „hello” на #weechat IRC канал (корисници на каналу ће видети поруку) buffer = weechat.info_get("irc_buffer", "libera,#weechat") weechat.command(buffer, "hello") ---- [[buffers_new]] ==== Креирање новог бафера У својој скрипти можете креирати нови бафер, па да га затим користите за приказ порука. Могу да се позову две функције повратног позива (нису обавезне): једна за улазне податке (када откуцате неки текст и притиснете [Ентер] у баферу), друга се позива када се бафер затвори (на пример, са `/buffer close`). Пример: [source,python] ---- # функција повратног позива за податке примљене са улаза def buffer_input_cb(data, buffer, input_data): # ... return weechat.WEECHAT_RC_OK # функција повратног позива која се позива када се бафер затвори def buffer_close_cb(data, buffer): # ... return weechat.WEECHAT_RC_OK # креирање бафера buffer = weechat.buffer_new("mybuffer", "buffer_input_cb", "", "buffer_close_cb", "") # постављање наслова weechat.buffer_set(buffer, "title", "Ово је наслов мог бафера.") # искључивање логовања, постављањем локалне променљиве „no_log” на „1” weechat.buffer_set(buffer, "localvar_set_no_log", "1") ---- [[buffers_properties]] ==== Особине бафера Особине бафера можете да читате као стринг, цели број или показивач. Примери: [source,python] ---- buffer = weechat.current_buffer() number = weechat.buffer_get_integer(buffer, "number") name = weechat.buffer_get_string(buffer, "name") short_name = weechat.buffer_get_string(buffer, "short_name") ---- Могyће је додавање, читање или брисање локалних променњивих у баферу: [source,python] ---- # додавање локалне променљиве weechat.buffer_set(buffer, "localvar_set_myvar", "my_value") # читање локалне променљиве myvar = weechat.buffer_get_string(buffer, "localvar_myvar") # брисање локалне променљиве weechat.buffer_set(buffer, "localvar_del_myvar", "") ---- Ако желите да видите локалне променљиве у баферу, извршите следећу комаду у програму WeeChat: ---- /buffer listvar ---- [[hooks]] === Куке [[hook_command]] ==== Додавање нове команде Нову команду додајете са `+hook_command+`. Можете да употребите шаблон прилагођеног довршавања за довршавање аргумената ваше команде. Пример: [source,python] ---- def my_command_cb(data, buffer, args): # ... return weechat.WEECHAT_RC_OK hook = weechat.hook_command("мојфилтер", "опис за мојфилтер", "[list] | [enable|disable|toggle [име]] | [add име plugin.buffer tags regex] | [del име|-all]", "опис аргумената...", "list" " || enable %(filters_names)" " || disable %(filters_names)" " || toggle %(filters_names)" " || add %(filters_names) %(buffers_plugins_names)|*" " || del %(filters_names)|-all", "my_command_cb", "") ---- Па затим у програму WeeChat: ---- /help мојфилтер /мојфилтер аргументи... ---- [[hook_timer]] ==== Додавање тајмера Тајмер се додаје са `+hook_timer+`. Пример: [source,python] ---- def timer_cb(data, remaining_calls): # ... return weechat.WEECHAT_RC_OK # тајмер се позива сваког минута када су секунде 00 weechat.hook_timer(60 * 1000, 60, 0, "timer_cb", "") ---- [[hook_process]] ==== Покретање процеса у позадини Процес можете да покренете у позадини са `+hook_process+`. Ваша функција повратног позива ће се позвати онда када подаци буду спремни. Може да се позива више пута. У последњем позиву ваше функције повратног позива, _return_code_ се поставља на 0 или позитивну вредност, то је повратни кôд команде. Пример: [source,python] ---- def my_process_cb(data, command, return_code, out, err): if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR: weechat.prnt("", "Error with command '%s'" % command) return weechat.WEECHAT_RC_OK if return_code >= 0: weechat.prnt("", "return_code = %d" % return_code) if out: weechat.prnt("", "stdout: %s" % out) if err: weechat.prnt("", "stderr: %s" % err) return weechat.WEECHAT_RC_OK weechat.hook_process("/bin/ls -l /etc", 10 * 1000, "my_process_cb", "") ---- Уместо спољне команде, такође можете директно да позовете скрипт функцију која ради нешто што блокира: [source,python] ---- def get_status(data): # do something blocking... # ... return "this is the result" def my_process_cb(data, command, return_code, out, err): if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR: weechat.prnt("", "Error with command '%s'" % command) return weechat.WEECHAT_RC_OK if return_code >= 0: weechat.prnt("", "return_code = %d" % return_code) if out: weechat.prnt("", "stdout: %s" % out) if err: weechat.prnt("", "stderr: %s" % err) return weechat.WEECHAT_RC_OK hook = weechat.hook_process("func:get_status", 5000, "my_process_cb", "") ---- [[url_transfer]] ==== URL пренос _Ново у верзији 0.3.7._ Ако желите да преузмете URL (или пошаљете на URL), морате да употребите функцију `+hook_process+`, или `+hook_process_hashtable+` ако је потребно да поставите опције URL преноса. Пример URL преноса без опције: HTML страница ће се примити као „out” у функцији повратног позива (стандардни излаз процеса): [source,python] ---- # Приказује последњу стабилну верзију WeeChat. weechat_latest_version = "" def weechat_process_cb(data, command, return_code, out, err): global weechat_latest_version if out: weechat_latest_version += out if return_code >= 0: weechat.prnt("", "Последња WeeChat верзија: %s" % weechat_latest_version) return weechat.WEECHAT_RC_OK weechat.hook_process("url:https://weechat.org/dev/info/stable/", 30 * 1000, "weechat_process_cb", "") ---- [TIP] Све информације у вези програма WeeChat се налазе на https://weechat.org/dev/info/[овој страници ^↗^^]. Пример URL преноса са опцијом: преузимање најновијег WeeChat развојног пакета у фајл _/tmp/weechat-devel.tar.gz_: [source,python] ---- def my_process_cb(data, command, return_code, out, err): if return_code >= 0: weechat.prnt("", "Крај преноса (return code = %d)" % return_code) return weechat.WEECHAT_RC_OK weechat.hook_process_hashtable("url:https://weechat.org/files/src/weechat-devel.tar.gz", {"file_out": "/tmp/weechat-devel.tar.gz"}, 30 * 1000, "my_process_cb", "") ---- За више информација у вези URL преноса, као и за доступне опције, погледајте функције `+hook_process+` и `+hook_process_hashtable+` у link:weechat_plugin_api.sr.html#_hook_process[WeeChat референтни приручник API додатака ^↗^^]. [[config_options]] === Конфигурација / опције [[config_options_set_script]] ==== Постављање опција за скрипту Функција `+config_is_set_plugin+` се користи за проверу да ли је опција постављена или не, а `+config_set_plugin+` за постављање опције. Пример: [source,python] ---- script_options = { "option1": "value1", "option2": "value2", "option3": "value3", } for option, default_value in script_options.items(): if not weechat.config_is_set_plugin(option): weechat.config_set_plugin(option, default_value) ---- [[config_options_detect_changes]] ==== Откривање измена Ако желите обавештење када корисник измени неке опције скрипте, морате да користите `+hook_config+`. Пример: [source,python] ---- SCRIPT_NAME = "myscript" # ... def config_cb(data, option, value): """Повратни позив се позива када се опција скрипте измени.""" # на пример, читање свих опција у променљиве скрипте... # ... return weechat.WEECHAT_RC_OK # ... weechat.hook_config("plugins.var.python." + SCRIPT_NAME + ".*", "config_cb", "") # за остале језике, измените „python” именом свој језика (perl/ruby/lua/tcl/guile/javascript) ---- [[config_options_weechat]] ==== Читање опција програма WeeChat Фунцкија `+config_get+` враћа показивач на опцију. Затим, у зависности од типа опције, морате да позовете `+config_string+`, `+config_boolean+`, `+config_integer+` или `+config_color+`. [source,python] ---- # string weechat.prnt("", "вредност опције weechat.look.item_time_format је: %s" % (weechat.config_string(weechat.config_get("weechat.look.item_time_format")))) # boolean weechat.prnt("", "вредност опције weechat.look.day_change је: %d" % (weechat.config_boolean(weechat.config_get("weechat.look.day_change")))) # integer weechat.prnt("", "вредност опције weechat.look.scroll_page_percent је: %d" % (weechat.config_integer(weechat.config_get("weechat.look.scroll_page_percent")))) # color weechat.prnt("", "вредност опције weechat.color.chat_delimiters је: %s" % (weechat.config_color(weechat.config_get("weechat.color.chat_delimiters")))) ---- [[irc]] === IRC [[irc_catch_messages]] ==== Хватање порука IRC додатак шаље четири сигнала за примљену поруку (`xxx` је IRC интерно име сервера, `yyy` је IRC име команде као што је JOIN, QUIT, PRIVMSG, 301, ...): xxx,irc_in_yyy:: сигнал који се шаље пре обраде поруке, само ако се порука *не* игнорише xxx,irc_in2_yyy:: сигнал који се шаље након обраде поруке, само ако се порука *не* игнорише xxx,irc_raw_in_yyy:: сигнал који се шаље пре обраде поруке, чак и ако се порука игнорише xxx,irc_raw_in2_yyy:: сигнал који се шаље након обраде поруке, чак и ако се порука игнорише [source,python] ---- def join_cb(data, signal, signal_data): # сигнал је на пример: „libera,irc_in2_join” # signal_data је IRC порука, на пример: „:nick!user@host JOIN :#channel” server = signal.split(",")[0] msg = weechat.info_get_hashtable("irc_message_parse", {"message": signal_data}) buffer = weechat.info_get("irc_buffer", "%s,%s" % (server, msg["channel"])) if buffer: weechat.prnt(buffer, "%s (%s) се придружио овом каналу!" % (msg["nick"], msg["host"])) return weechat.WEECHAT_RC_OK # овде је корисни да се као сервер употреби „*”, како би се хватале JOIN поруке # на свим IRC серверима weechat.hook_signal("*,irc_in2_join", "join_cb", "") ---- [[irc_modify_messages]] ==== Измена порука IRC додатак шаље два „модификатора” за сваку примљену поруку („xxx” је IRC команда), тако да можете да је измените: irc_in_xxx:: модификатор који се шаље пре декодирања у скуп карактера: користите уз опрез, стринг може да садржи неважеће UTF-8 податке; користите само за сирове операције над поруком irc_in2_xxx:: модификатор који се шаље након декодирања у скуп карактера, тако да је примљени стринг увек важећи UTF-8 (*препоручује се*) [source,python] ---- def modifier_cb(data, modifier, modifier_data, string): # у све примљене поруке се додаје име сервера # (OK ово и није баш корисно, али то је само пример!) return "%s %s" % (string, modifier_data) weechat.hook_modifier("irc_in2_privmsg", "modifier_cb", "") ---- [WARNING] Неправилно формирана порука би могла да сруши програм WeeChat или да изазове озбиљне проблеме! [[irc_message_parse]] ==== Парсирање поруке _Ново у верзији 0.3.4._ IRC поруку можете да парсирате са info_hashtable под именом „irc_message_parse”. Резултат је хеш табела са следећим кључевима (вредности за пример су изграђене из следеће поруке: `+@time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :здраво!+`): [width="100%", cols="3,^2,10,7", options="header"] |=== | Кључ | Од WeeChat ^(1)^ | Опис | Пример | tags | 0.4.0 | Ознаке у поруци (може бити празно). | `+time=2015-06-27T16:40:35.000Z+` | tag_xxx | 3.3 | Неозначена вредност ознаке "xxx" (један кључ по ознаци). | `+2015-06-27T16:40:35.000Z+` | message_without_tags | 0.4.0 | Порука без ознака (иста као оригинална ако нема ознака у њој). | `+:nick!user@host PRIVMSG #weechat :здраво!+` | nick | 0.3.4 | Надимак порекла. | `+nick+` | user | 2.7 | Корисник порекла. | `+user+` | host | 0.3.4 | Хост порекла (укључујући и надимак). | `+nick!user@host+` | command | 0.3.4 | Команда (_PRIVMSG_, _NOTICE_, ...). | `+PRIVMSG+` | channel | 0.3.4 | Циљни канал. | `+#weechat+` | arguments | 0.3.4 | Аргументи команде (укључујући и канал). | `+#weechat :здраво!+` | text | 1.3 | Текст (на пример, корисникова порука). | `+здраво!+` | paramN | 3.4 | Параметар команде (од 1 до N). | `+#weechat+` | num_params | 3.4 | Број параметара команде. | `+2+` | pos_command | 1.3 | Индекс _command_ у поруци („-1” ако се _command_ не пронађе). | `+47+` | pos_arguments | 1.3 | Индекс _arguments_ у поруци („-1” ако се _arguments_ не пронађе). | `+55+` | pos_channel | 1.3 | Индекс _channel_ у поруци („-1” ако се _channel_ не пронађе). | `+55+` | pos_text | 1.3 | Индекс _text_ у поруци („-1” ако се _text_ не пронађе). | `+65+` |=== [NOTE] ^(1)^ Овај кључ је уведен у наведеној верзији програма WeeChat [source,python] ---- dict = weechat.info_get_hashtable( "irc_message_parse", {"message": "@time=2015-06-27T16:40:35.000Z;tag2=value\\sspace :nick!user@host PRIVMSG #weechat :здраво!"}) # dict == { # "tags": "time=2015-06-27T16:40:35.000Z;tag2=value\\sspace", # "tag_time": "2015-06-27T16:40:35.000Z", # "tag_tag2": "value space", # "message_without_tags": ":nick!user@host PRIVMSG #weechat :здраво!", # "nick": "nick", # "user": "user", # "host": "nick!user@host", # "command": "PRIVMSG", # "channel": "#weechat", # "arguments": "#weechat :здраво!", # "text": "hello!", # "param1": "#weechat", # "param2": "hello!", # "num_params": "2", # "pos_command": "65", # "pos_arguments": "73", # "pos_channel": "73", # "pos_text": "83", # } ---- [[infos]] === Информације [[infos_weechat_version]] ==== Верзија програма WeeChat Најбољи начин да се провери верзија је да се затражи „version_number”, па да се уради целобројно поређење са хексадецималним бројем верзије. Пример: [source,python] ---- version = weechat.info_get("version_number", "") or 0 if int(version) >= 0x00030200: weechat.prnt("", "Ово је WeeChat 0.3.2 или новији") else: weechat.prnt("", "Ово је WeeChat 0.3.1 или старији") ---- [NOTE] Верзије ≤ 0.3.1.1 враћају празан стринг за _info_get("version_number")_ тако да морате проверити да враћена вредност *није* празна. Да бисте добили верзију као стринг: [source,python] ---- # ово ће да испише на пример „Верзија 0.3.2” weechat.prnt("", "Верзија %s" % weechat.info_get("version", "")) ---- [[infos_other]] ==== Остале информације [source,python] ---- # WeeChat конфиг директоријум, на пример: „/home/user/.config/weechat” weechat.prnt("", "WeeChat конфиг дир: %s" % weechat.info_get("weechat_dir", "")) # неактивност тастатуре weechat.prnt("", "Неактивно је %s секунди" % weechat.info_get("inactivity", "")) ---- [[infolists]] === Инфолисте [[infolists_read]] ==== Читање инфолисте Можете да читате инфолисту коју изгради WeeChat или остали додаци. Пример: [source,python] ---- # читање infolist „buffer”, како би се добила листа бафера infolist = weechat.infolist_get("buffer", "", "") if infolist: while weechat.infolist_next(infolist): name = weechat.infolist_string(infolist, "name") weechat.prnt("", "бафер: %s" % name) weechat.infolist_free(infolist) ---- [IMPORTANT] Не заборавите да позовете `+infolist_free+` како бисте ослободите меморију коју користи infolist, јер програм WeeChat неће аутоматски ослободити меморију.