= Poradnik pisania skryptów WeeChat :author: Sébastien Helleu :email: flashcode@flashtux.org :lang: pl :toc: left :toclevels: 3 :toc-title: Spis treści :sectnums: :docinfo1: Tłumaczenie: * Krzysztof Korościk , 2009-2016 Ten dokument opisuje klienta rozmów WeeChat, który jest częścią WeeChat. Najnowsza wersja tego dokumentu znajduje się na tej stronie: https://weechat.org/doc [[introduction]] == Wprowadzenie WeeChat (Wee Enhanced Environment for Chat) jest darmowym klientem rozmów, szybkim i lekkim, zaprojektowanym dla wielu systemów operacyjnych. Ten dokument przedstawia sposób pisania skryptów dla WeeChat z użyciem jednego ze wspieranych języków skryptowych: * Python * Perl * Ruby * Lua * Tcl * Guile (Scheme) * JavaScript * PHP [NOTE] Prawie wszystkie przykłady umieszczone w tym dokumencie są napisane w Pythonie, ale API jest takie same dla wszystkich języków. [[scripts_in_weechat]] == Skrypty w WeeChat [[weechat_architecture]] === Architektura WeeChat WeeChat jest jednowątkowy, dotyczy to również skryptów. Kod skryptu jest wykonywany: * kiedy skrypt jest ładowany, zazwyczaj wywołanie <> * kiedy WeeChat wywoła callback hooka (zobacz rozdział <>). Kiedy wykonywany jest kod skryptu, WeeChat czeka na koniec wykonania zanim przejdzie dalej. Dlatego skrypty *NIE* mogą wykonywac operacji blokujących jak operacje sieciowe bez użycia dedykowanej funkcji API jak `hook_process`. [IMPORTANT] Skrypt *NIGDY* nie powinien się mnożyć ani tworzyć wątków bez użycia dedykowanych funkcji API, może to prowadzić to awarii WeeChat. + Jeśli coś musi zostać wykonane w tle, można użyć funkcji `hook_process`. Zobacz przykład w rozdziale <> oraz dokumentację do funkcji `hook_process` w link:weechat_plugin_api.en.html#_hook_process[Opisu API wtyczek WeeChat] (Angielski). [[languages_specificities]] === Specyfika języków ==== Python * Należy wykonać `import weechat` * Funkcje `+print*+` są nazwane `+prnt*+` w pythonie (ponieważ _print_ jest zastrzeżonym słowem kluczowym) * Funkcje są wywoływane za pomocą `weechat.xxx(arg1, arg2, ...)` ==== Perl * Funkcje są wywoływane za pomocą `weechat::xxx(arg1, arg2, ...);` ==== Ruby * Trzeba zdefiniować _weechat_init_ i wywołać _register_ wewnątrz * Funkcje są wywoływane za pomocą `Weechat.xxx(arg1, arg2, ...)` * W związku z ograniczeniami Ruby (maksymalnie 15 argumentów dla funkcji), funkcja `Weechat.config_new_option` otrzymuje callbacki w postaci tablicy 6 ciągów (3 callbacki + 3 ciągi danych), wywołanie tej funkcji wygląda następująco: [source,ruby] ---- Weechat.config_new_option(config, section, "nazwa", "ciąg", "opis opcji", "", 0, 0, "wartość", "wartość", 0, ["check_cb", "", "change_cb", "", "delete_cb", ""]) ---- ==== Lua * Funkcje są wywoływane za pomocą `weechat.xxx(arg1, arg2, ...)` ==== Tcl * Funkcje są wywoływane za pomocą `weechat::xxx arg1 arg2 ...` ==== Guile (Scheme) * Funkcje są wywoływane za pomocą `(weechat:xxx arg1 arg2 ...)` * Następujące funkcje przyjmują pojedynczą listę argumentów (zamiast wielu argumentów dla innych funkcji), ponieważ ilość argumentów przekracza ilość argumentów dozwolonych w Guile: ** config_new_section ** config_new_option ** bar_new ==== JavaScript * Funkcje są wywoływane za pomocą `weechat.xxx(arg1, arg2, ...);` ==== PHP * Funkcje są wywoływane za pomocą `weechat_xxx(arg1, arg2, ...);` [[register_function]] === Funkcja rejestrująca Wszystkie skrypty WeeChat muszą się "zarejestrować" w WeeChat, musi to być pierwsza z funkcji WeeChat wywołana w skrypcie. Prototyp: [source,python] ---- weechat.register(nazwa, autor, wersja, licencja, opis, funkcja_wyłączająca, kodowanie) ---- Argumenty: * _nazwa_: string, wewnętrzna nazwa skryptu * _autor_: string, autor skryptu * _wersja_: string, wersja * _licencja_: string, licencja * _opis_: string, krótki opis skryptu * _funkcja_wyłączająca_: string, nazwa funkcji wywoływanej podczas wyładowania skryptu (może być pusty ciąg) * _kodowanie_: string, kodowane skryptu (jeśli skrypt jest napisany w UTF-8 można nie podawać tej wartości - UTF-8 to domyślne kodowanie) Przykład dla skryptu w każdym z języków: * Python: [source,python] ---- import weechat weechat.register("test_python", "FlashCode", "1.0", "GPL3", "Skrypt testowy", "", "") weechat.prnt("", "Witaj z pythonowego skryptu!") ---- * Perl: [source,perl] ---- weechat::register("test_perl", "FlashCode", "1.0", "GPL3", "Skrypt testowy", "", ""); weechat::print("", "Witaj z perlowego skryptu!"); ---- * Ruby: [source,ruby] ---- def weechat_init Weechat.register("test_ruby", "FlashCode", "1.0", "GPL3", "Skrypt testowy", "", "") Weechat.print("", "Witaj ze skryptu ruby!") return Weechat::WEECHAT_RC_OK end ---- * Lua: [source,lua] ---- weechat.register("test_lua", "FlashCode", "1.0", "GPL3", "Skrypt testowy", "", "") weechat.print("", "Witaj ze skryptu lua!") ---- * Tcl: [source,tcl] ---- weechat::register "test_tcl" "FlashCode" "1.0" "GPL3" "Skrypt testowy" "" "" weechat::print "" "Witaj ze skryptu tcl!" ---- * Guile (Scheme): [source,lisp] ---- (weechat:register "test_scheme" "FlashCode" "1.0" "GPL3" "Skrypt testowy" "" "") (weechat:print "" "Witaj ze skryptu scheme!") ---- * JavaScript: [source,javascript] ---- weechat.register("test_js", "FlashCode", "1.0", "GPL3", "Skrypt testowy", "", ""); weechat.print("", "Witaj ze skryptu javascript!"); ---- * PHP: [source,php] ---- weechat_register('test_php', 'FlashCode', '1.0', 'GPL3', 'Skrypt testowy', '', ''); weechat_print('', 'Witaj ze skryptu PHP!'); ---- [[load_script]] === Ładowanie skryptu Zaleca się używanie wtyczki "script" do ładowania skryptów, na przykład: ---- /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 ---- Każdy język posiada również swoją własną komendę: ---- /python load skrypt.py /perl load skrypt.pl /ruby load skrypt.rb /lua load skrypt.lua /tcl load skrypt.tcl /guile load skrypt.scm /javascript load skrypt.js /php load skrypt.php ---- Możesz zrobić dowiązanie w katalogu _język/autoload_ jeśli chcesz automatycznie ładować skrypt po uruchomieniu WeeChat. Na przykład dla Pythona: ---- $ cd ~/.weechat/python/autoload $ ln -s ../skrypt.py ---- [NOTE] Podczas instalacji skryptu za pomocą `/script install` automatycznie tworzone jest dowiązanie w katalogu _autoload_. [[differences_with_c_api]] == Różnice pomiędzy API dla C API skryptów jest prawie takie same jak API dla wtyczek pisanych w C. Możesz zajrzeć do link:weechat_plugin_api.en.html[Opisu API wtyczek WeeChat] (Angielski) po więcej informacji na temat każdej z funkcji API: prototyp, argumenty, zwracane wartości, przykłady. Ważne jest rozróżnienie _wtyczki_ od _skryptu_: _wtyczka_ jest plikiem binarnym skompilowanym i załadowanym za pomocą komendy `/plugin`, natomiast _skrypt_ jest plikiem tekstowym załadowanym przez wtyczkę jak _python_ za pomocą komendy `/python`. W momencie, kiedy Twój skrypt _test.py_ wywołuje funkcję z API WeeChat, wygląda to tak: .... ┌────────────────────────┐ ╔══════════════════╗ │ wtyczka python │ ║ WeeChat "core" ║ ├──────────────┬─────────┤ ╟─────────┐ ║ test.py ─────► │ API skryptów │ C API │ ─────► ║ C API │ ║ └──────────────┴─────────┘ ╚═════════╧════════╝ .... Kiedy WeeChat odwołuje się do Twojego skryptu _test.py_ wygląda to tak: .... ╔══════════════════╗ ┌────────────────────────┐ ║ WeeChat "core" ║ │ wtyczka python │ ║ ┌─────────╢ ├─────────┬──────────────┤ ║ │ C API ║ ─────► │ C API │ API skryptów │ ─────► test.py ╚════════╧═════════╝ └─────────┴──────────────┘ .... [[pointers]] === Wskaźniki Jak już zapewne wiecie nie ma prawdziwych "wskaźników" w skryptach. Dlatego kiedy funkcja API zwraca wskaźnik, jest on konwertowany na ciąg dla skryptu. Na przykład, jeśli funkcja zwraca wskaźnik 0x1234ab56 skrypt otrzyma ciąg "0x1234ab56". W sytuacji, kiedy funkcja API spodziewa się wskaźnika jako argumentu skrypt musi przekazać go jako ciąg. Wtyczki napisane w C przekonwertują go na prawdziwy wskaźnik, zanim wywołają funkcję z API C. Dozwolone są puste ciągi lub "0x0", oznaczają NULL w C. Na przykład, aby wyświetlić dane w rdzennym buforze (główny bufor WeeChat): [source,python] ---- weechat.prnt("", "hi!") ---- [WARNING] W wielu funkcjach, z powodów wydajności, WeeChat nie sprawdza poprawności wskaźników. Do ciebie należy sprawdzenie poprawności przekazywanych wskaźników, w innym wypadku możesz zobaczyć ładny raport o błędzie ;) [[callbacks]] === Callbacki Prawie wszystkie callbacki muszą zwrócić WEECHAT_RC_OK lub WEECHAT_RC_ERROR (wyjątkiem jest callback modyfikujący, który zwraca ciąg). Callbacki C używają argumentu "data", który jest wskaźnikiem. W API skryptów, "data" jest ciągiem o dowolnej wartości (nie jest wskaźnikiem). Przykłady callbacków dla każdego języka: * 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 skryptów Więcej informacji o funkcjach w API, znajdziesz w link:weechat_plugin_api.en.html[Opisu API wtyczek WeeChat] (Angielski). [[script_api_functions]] === Fukcje Lista funkcji w API skryptów: [width="75%",cols="1,3",options="header"] |=== | Kategoria | Funkcje | ogólne | register | wtyczki | plugin_get_name | ciągi | 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_remove_color + string_is_command_char + string_input_for_buffer + string_eval_expression + string_eval_path_home | katalogi | mkdir_home + mkdir + mkdir_parents | przechowywane listy | 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 | pliki konfiguracyjne | 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 | przypisania klawiszy | key_bind + key_unbind | wyświetlanie | prefix + color + print (dla pythona: prnt) + print_date_tags (dla pythona: prnt_date_tags) + print_y (dla pythona: prnt_y) + log_print | hooks | 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_completion_get_string + hook_completion_list_add + hook_modifier + hook_modifier_exec + hook_info + hook_info_hashtable + hook_infolist + hook_focus + hook_set + unhook + unhook_all | bufory | buffer_new + 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 | okna | current_window + window_search_with_buffer + window_get_integer + window_get_string + window_get_pointer + window_set_title | lista nicków | 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 | paski | bar_item_search + bar_item_new + bar_item_update + bar_item_remove + bar_search + bar_new + bar_set + bar_update + bar_remove | komendy | command + command_options | informacje | info_get + info_get_hashtable | infolisty | 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 | uaktualnienie | upgrade_new + upgrade_write_object + upgrade_read + upgrade_close |=== [[script_api_constants]] === Stałe Lista stałych w API skryptów: [width="75%",cols="1,3",options="header"] |=== | Kategoria | Stałe | zwracane kody | WEECHAT_RC_OK + WEECHAT_RC_OK_EAT + WEECHAT_RC_ERROR | pliki konfiguracyjne | 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 | posortowane listy | WEECHAT_LIST_POS_SORT + WEECHAT_LIST_POS_BEGINNING + WEECHAT_LIST_POS_END | hotlisty | WEECHAT_HOTLIST_LOW + WEECHAT_HOTLIST_MESSAGE + WEECHAT_HOTLIST_PRIVATE + WEECHAT_HOTLIST_HIGHLIGHT | hook process | WEECHAT_HOOK_PROCESS_RUNNING + WEECHAT_HOOK_PROCESS_ERROR | hook 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 | hook signal | WEECHAT_HOOK_SIGNAL_STRING + WEECHAT_HOOK_SIGNAL_INT + WEECHAT_HOOK_SIGNAL_POINTER |=== [[common_tasks]] == Częste zadania Ten rozdział przedstawia część częstych zadań z przykładami. Użyto tu tylko część rzeczy dostępnych w API, dokładne informacje można znaleźć w link:weechat_plugin_api.en.html[Opisu API wtyczek WeeChat] (Angielski). [[buffers]] === Bufory [[buffers_display_messages]] ==== Wyświetlanie wiadomości Pusty ciąg jest często używany podczas pracy z głównym buforem WeeChat. Dla pozostałych buforów należy podać wskaźnik (jako ciąg, zobacz <>). Przykłady: [source,python] ---- # wyświetl "witaj" w głównym buforze weechat.prnt("", "witaj") # wyświetl "witaj" w głównym buforze, ale nie zapisuj tego do pliku z logiem # (tylko wersje >= 0.3.3) weechat.prnt_date_tags("", 0, "no_log", "witaj") # wyświetl "==>" przed wiadomością "witaj" w obecnym buforze # (przedrostek i wiadomość muszą być oddzielone znakiem tabulacji) weechat.prnt(weechat.current_buffer(), "==>\twitaj") # wyświetla wiadomość o błędzie w głównym buforze (z przedrostkiem błąd) weechat.prnt("", "%szłe argumenty" % weechat.prefix("błąd")) # wyświetl wiadomość z kolorem w głównym buforze weechat.prnt("", "text %sżółty na niebieskim" % weechat.color("yellow,blue")) # przeszuka bufor i wyświetli wiadomość # (pełna nazwa bufora to wtyczka.nazwa, na przykład: "irc.freenode.#weechat") buffer = weechat.buffer_search("irc", "freenode.#weechat") weechat.prnt(buffer, "wiadomość na kanale #weechat") # inne rozwiązanie na znalezienie bufora IRC (lepsze) # (zauważ, że serwer i kanał są oddzielone przecinkiem) buffer = weechat.info_get("irc_buffer", "freenode,#weechat") weechat.prnt(buffer, "wiadomość na kanale #weechat") ---- [NOTE] Funkcja print dla języka Python nazywa się `prnt`, dla pozostałych `print`. [[buffers_send_text]] ==== Wysyłanie tekstu do bufora Możesz wysłać tekst lub komendę do bufora. Dokładnie tak jakby wpisać tekst w linii poleceń i wcisnąć [Enter]. Przykłady: [source,python] ---- # wykona polecenie "/help" w obecnym buforze (wyświetli się w głównym buforze) weechat.command("", "/help") # wyśle "witaj" na kanał #weechat (użytkownicy na kanale zobaczą wiadomość) buffer = weechat.info_get("irc_buffer", "freenode,#weechat") weechat.command(buffer, "witaj") ---- [[buffers_new]] ==== Tworzenie nowego buforu Możesz stworzyć nowy bufor w skrypcie, następnie użyć go do wyświetlania wiadomości. Dwa callbacki mogą zostać wywołane (są opcjonalne): jeden dla danych wejściowych (kiedy wpiszesz tekst i naciśniesz [Enter] w buforze), drugi jest wywoływany podczas zamykania bufora (na przykład przez `/buffer close`). Przykłady: [source,python] ---- # callback dla danych otrzymanych na wejściu def buffer_input_cb(data, buffer, input_data): # ... return weechat.WEECHAT_RC_OK # callback wywoływany przy zamknięciu bufora def buffer_close_cb(data, buffer): # ... return weechat.WEECHAT_RC_OK # tworzenie bufora buffer = weechat.buffer_new("mybuffer", "buffer_input_cb", "", "buffer_close_cb", "") # ustawianie tytułu weechat.buffer_set(buffer, "title", "To jest tytuł mojego buforu.") # wyłącza logowanie, przez ustawienie zmiennej lokalnej "no_log" na "1" weechat.buffer_set(buffer, "localvar_set_no_log", "1") ---- [[buffers_properties]] ==== Właściwości buforów Możesz odczytać właściwości buforów jako ciąg, liczbę lub wskaźnik. Przykłady: [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") ---- Możliwe jest dodanie, odczytanie lub kasowanie lokalnych zmiennych dla buforów: [source,python] ---- # dodanie zmiennej lokalnej weechat.buffer_set(buffer, "localvar_set_myvar", "my_value") # odczyt zmiennej lokalnej myvar = weechat.buffer_get_string(buffer, "localvar_myvar") # kasowanie zmiennej lokalnej weechat.buffer_set(buffer, "localvar_del_myvar", "") ---- Aby zobaczyć lokalne zmienne danego bufora, należy wykonać tą komendę w WeeChat: ---- /buffer localvar ---- [[hooks]] === Hooki [[hook_command]] ==== Dodanie nowej komendy Aby dodać nową komendę należy użyć `hook_command`. Można użyć własnego szablonu dopełnień dla uzupełniania argumentów własnej komendy. Przykład: [source,python] ---- def my_command_cb(data, buffer, args): # ... return weechat.WEECHAT_RC_OK hook = weechat.hook_command("myfilter", "opis myfilter", "[list] | [enable|disable|toggle [name]] | [add name plugin.buffer tags regex] | [del name|-all]", "description of arguments...", "list" " || enable %(filters_names)" " || disable %(filters_names)" " || toggle %(filters_names)" " || add %(filters_names) %(buffers_plugins_names)|*" " || del %(filters_names)|-all", "my_command_cb", "") ---- Następnie w WeeChat: ---- /help myfilter /myfilter argumenty... ---- [[hook_timer]] ==== Dodanie timera Do dodania timera służy `hook_timer`. Przykład: [source,python] ---- def timer_cb(data, remaining_calls): # ... return weechat.WEECHAT_RC_OK # timer wywoływany co minutę, kiedy liczba sekund wynosi 00 weechat.hook_timer(60 * 1000, 60, 0, "timer_cb", "") ---- [[hook_process]] ==== Wykonanie procesu w tle Do wykonywania procesów w tle służy `hook_process`. Twoje callbacki zostaną wywołane, kiedy dane będą gotowe. Może zostać wywołane wiele razy. Dla ostatniego wykonania Twojego callbacku _rc_ jest ustawiane na 0, lub wartość dodatnią, jest to kod zwracany przez komendę. Przykład: [source,python] ---- process_output = "" def my_process_cb(data, command, rc, out, err): global process_output if out != "": process_output += out if int(rc) >= 0: weechat.prnt("", process_output) return weechat.WEECHAT_RC_OK weechat.hook_process("/bin/ls -l /etc", 10 * 1000, "my_process_cb", "") ---- [[url_transfer]] ==== Transfer URL _Nowe w wersji 0.3.7._ Aby pobrać URL (albo wysłać do URL), należy użyć funkcji `hook_process`, lub `hook_process_hashtable` jeśli konieczne jest przekazanie parametrów. Przykład transferu URL bez opcji: strona HTML jest otrzymywana jako "out" (standardowe wyjście procesu): [source,python] ---- # Wyświetla aktualną stabilną wersję WeeChat. weechat_version = "" def weechat_process_cb(data, command, rc, out, err): global weechat_version if out != "": weechat_version += out if int(rc) >= 0: weechat.prnt("", "Obecna wersja stabilna WeeChat: %s" % weechat_version) return weechat.WEECHAT_RC_OK weechat.hook_process("url:https://weechat.org/dev/info/stable/", 30 * 1000, "weechat_process_cb", "") ---- [TIP] Wszystkie informacje o WeeChat dostępne są na stronie https://weechat.org/dev/info Przykładowy transfer URL z opcją: pobranie najnowszej wersji rozwojowej WeeChat do pliku _/tmp/weechat-devel.tar.gz_: [source,python] ---- def my_process_cb(data, command, rc, out, err): if int(rc) >= 0: weechat.prnt("", "End of transfer (rc=%s)" % rc) 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", "") ---- Więcej informacji o transferach URL i dostępnych opcjach dla funkcji `hook_process` oraz `hook_process_hashtable` można znaleźć w link:weechat_plugin_api.en.html#_hook_process[Opisu API wtyczek WeeChat] (Angielski). [[config_options]] === Konfiguracja / opcje [[config_options_set_script]] ==== Ustawianie opcji dla skryptu Funkcja `config_is_set_plugin` używana jest do sprawdzenia czy opcja jest ustawiona, `config_set_plugin` ustawia opcję. Example: [source,python] ---- script_options = { "opcja1": "wartość1", "opcja2": "wartość2", "opcja3": "wartość3", } 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]] ==== Wykrywanie zmian Do wykrywania zmian opcji skryptu służy `hook_config`. Przykład: [source,python] ---- SCRIPT_NAME = "myscript" # ... def config_cb(data, option, value): """Callback called when a script option is changed.""" # na przykład, odczyt wszystkich opcji skryptu... # ... return weechat.WEECHAT_RC_OK # ... weechat.hook_config("plugins.var.python." + SCRIPT_NAME + ".*", "config_cb", "") # dla innych języków, zmień "python" na swój język (perl/ruby/lua/tcl/guile/javascript) ---- [[config_options_weechat]] ==== Odczyt opcji WeeChat Funkcja `config_get` zwraca wskaźnik do opcji. Następnie, w zależności od typu opcji, należy wywołać `config_string`, `config_boolean`, `config_integer` lub `config_color`. [source,python] ---- # string weechat.prnt("", "wartość opcji weechat.look.item_time_format to: %s" % (weechat.config_string(weechat.config_get("weechat.look.item_time_format")))) # boolean weechat.prnt("", "wartość opcji weechat.look.day_change to: %d" % (weechat.config_boolean(weechat.config_get("weechat.look.day_change")))) # integer weechat.prnt("", "wartość opcji weechat.look.scroll_page_percent to: %d" % (weechat.config_integer(weechat.config_get("weechat.look.scroll_page_percent")))) # color weechat.prnt("", "wartość opcji weechat.color.chat_delimiters to: %s" % (weechat.config_color(weechat.config_get("weechat.color.chat_delimiters")))) ---- [[irc]] === IRC [[irc_catch_messages]] ==== Przechwytywanie wiadomości Wtyczka IRC wysyła dwa sygnały dla otrzymanej wiadomości (`xxx` jest wewnętrzną nazwą serwera IRC, `yyy` to komenda IRC jak JOIN, QUIT, PRIVMSG, 301, ..): xxxx,irc_in_yyy:: sygnał wysłany przed przetworzeniem wiadomości xxx,irc_in2_yyy:: sygnał wysłany po przetworzeniu wiadomości [source,python] ---- def join_cb(data, sygnał, signal_data): # sygnał to na przykład: "freenode,irc_in2_join" # signal_data to wiadomość IRC, na przykład: ":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) has joined this channel!" % (msg["nick"], msg["host"])) return weechat.WEECHAT_RC_OK # przydatne jest użycie "*" jako serwera, aby złapać wiadomość JOIN na wszystkich # serwerach IRC weechat.hook_signal("*,irc_in2_join", "join_cb", "") ---- [[irc_modify_messages]] ==== Modyfikowanie wiadomości Wtyczka IRC wysyła "modyfikator" nazwany "irc_in_xxx" ("xxx" to komenda IRC) dla otrzymanej wiadomości, żeby można było ją zmodyfikować. [source,python] ---- def modifier_cb(data, modifier, modifier_data, string): # dodaje nazwę serwera do wszystkich otrzymanych wiadomości # (nie jest to może bardzo przydatne, ale to tylko przykład!) return "%s %s" % (string, modifier_data) weechat.hook_modifier("irc_in_privmsg", "modifier_cb", "") ---- [WARNING] Zniekształcone wiadomości mogą uszkodzić WeeChat, lub spowodować wiele problemów! [[irc_message_parse]] ==== Przetwarzanie wiadomości _Nowe w wersji 0.3.4._ Można przetwarzać wiadomości IRC za pomocą info_hashtable zwanej "irc_message_parse". Wynik jest tabela hashy z następującymi kluczami (przykładowe wartości zostały uzyskane za pomocą wiadomości: `@time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello!`): [width="100%",cols="1,^2,10,8",options="header"] |=== | Klucz | Wersja WeeChat | Opis | Przykład | tags | ≥ 0.4.0 | Tagi w wiadomości (mogą byc puste). | `time=2015-06-27T16:40:35.000Z` | message_without_tags | ≥ 0.4.0 | Wiadomość bez tagów (jeśli nie ma tagów jest to to samo co wiadomość). | `:nick!user@host PRIVMSG #weechat :hello!` | nick | ≥ 0.3.4 | Nick żródła. | `nick` | host | ≥ 0.3.4 | Host żródła (zawiera nick). | `nick!user@host` | command | ≥ 0.3.4 | Komenda (_PRIVMSG_, _NOTICE_, ...). | `PRIVMSG` | channel | ≥ 0.3.4 | Docelowy kanał. | `#weechat` | arguments | ≥ 0.3.4 | Argumenty komendy (zawierają kanał). | `#weechat :hello!` | text | ≥ 1.3 | Tekst (na przykład wiadomość użytkownika). | `hello!` | pos_command | ≥ 1.3 | The index of _command_ in message ("-1" if _command_ was not found). | `47` | pos_arguments | ≥ 1.3 | The index of _arguments_ in message ("-1" if _arguments_ was not found). | `55` | pos_channel | ≥ 1.3 | The index of _channel_ in message ("-1" if _channel_ was not found). | `55` | pos_text | ≥ 1.3 | The index of _text_ in message ("-1" if _text_ was not found). | `65` |=== [source,python] ---- dict = weechat.info_get_hashtable( "irc_message_parse", {"message": "@time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello!"}) # dict == { # "tags": "time=2015-06-27T16:40:35.000Z", # "message_without_tags": ":nick!user@host PRIVMSG #weechat :hello!", # "nick": "nick", # "host": "nick!user@host", # "command": "PRIVMSG", # "channel": "#weechat", # "arguments": "#weechat :hello!", # "text": "hello!", # "pos_command": "47", # "pos_arguments": "55", # "pos_channel": "55", # "pos_text": "65", # } ---- [[infos]] === Informacje [[infos_weechat_version]] ==== Wersja WeeChat Najprostszym sposobem na sprawdzenie wersji to pozyskanie "version_number" i wykonanie porównania między liczbą całkowitą a heksadecymalnym numerem wersji. Przykład: [source,python] ---- version = weechat.info_get("version_number", "") or 0 if int(version) >= 0x00030200: weechat.prnt("", "This is WeeChat 0.3.2 or newer") else: weechat.prnt("", "This is WeeChat 0.3.1 or older") ---- [NOTE] Wersje ≤ 0.3.1.1 zwracają pusty ciąg dla _info_get("version_number")_ należy sprawdzić, czy zwracana wartość *nie* jest pusta. Aby otrzymać ciąg z numerem wersji: [source,python] ---- # wyświetli to na przykład "Version 0.3.2" weechat.prnt("", "Version %s" % weechat.info_get("version", "")) ---- [[infos_other]] ==== Inne informacje [source,python] ---- # katalog domowy WeeChat, na przykład: "/home/xxxx/.weechat" weechat.prnt("", "Katalog domowy WeeChat: %s" % weechat.info_get("weechat_dir", "")) # nieaktywność klawiatury weechat.prnt("", "Nieaktywny od %s sekund" % weechat.info_get("inactivity", "")) ---- [[infolists]] === Infolisty [[infolists_read]] ==== Odczytanie infolisty Można odczytać infolisty wbudowane w WeeChat lub inne wtyczki. Przykład: [source,python] ---- # odczyta infolistę "buffer", aby otrzymać listę buforów infolist = weechat.infolist_get("buffer", "", "") if infolist: while weechat.infolist_next(infolist): name = weechat.infolist_string(infolist, "name") weechat.prnt("", "buffer: %s" % name) weechat.infolist_free(infolist) ---- [IMPORTANT] Nie zapomnij wywołać `infolist_free`, aby zwolnić pamięć użyta przez infolistę, ponieważ WeeChat nie zwolni automatycznie tej pamięci.