= Guida allo Scripting di WeeChat :author: Sébastien Helleu :email: flashcode@flashtux.org :lang: it :toc: left :toclevels: 3 :toc-title: Indice :sectnums: :docinfo1: // TRANSLATION MISSING Translators: * Marco Paolone , 2010-2013 Questo manuale documenta il client di chat WeeChat, ed è parte del programma stesso. La versione più recente di questo documento si trova qui: https://weechat.org/doc [[introduction]] == Introduzione WeeChat (Wee Enhanced Environment for Chat) è un client di chat libero, veloce e leggero, realizzato per molti sistemi operativi. Questo manuale documenta come scrivere script per WeeChat, usando uno dei linguaggi di scripting supportati: * Python * Perl * Ruby * Lua * Tcl * Guile (Scheme) * Javascript * PHP [NOTE] Quasi tutti gli esempi in questo manuale sono scritti in Python, ma l'API è identica per gli altri linguaggi. [[scripts_in_weechat]] == Script in WeeChat [[languages_specificities]] === Specifiche per i linguaggi ==== Python * E necessario `import weechat` * Le funzioni `+print*+` sono chiamate `+prnt*+` in python (dato che _print_ è una parola riservata) * Le funzioni sono chiamate con `weechat.xxx(arg1, arg2, ...)` ==== Perl * Le funzioni sono chiamate con `weechat::xxx(arg1, arg2, ...);` ==== Ruby * E necessario definire _weechat_init_ e chiamare _register_ all'interno * Le funzioni sono chiamate con `Weechat.xxx(arg1, arg2, ...)` * A causa di una limitazione di Ruby (massimo 15 argomenti per funzione), la funzione `WeeChat.config_new_option` riceve le callback in un array di 6 stringhe (3 callback + 3 stringhe di dati), così che una chiamata a questa funzione appare come: [source,ruby] ---- Weechat.config_new_option(config, section, "name", "string", "description of option", "", 0, 0, "value", "value", 0, ["check_cb", "", "change_cb", "", "delete_cb", ""]) ---- ==== Lua * Le funzioni sono chiamate con `weechat.xxx(arg1, arg2, ...)` ==== Tcl * Le funzioni sono chiamate con `weechat::xxx arg1 arg2 ...` ==== Guile (Scheme) * Le funzioni sono chiamate con `(weechat:xxx arg1 arg2 ...)` * Le seguenti funzioni prendono un elenco di argomenti (invece di più argomenti come per le altre funzioni), poiché il numero di argomenti eccede il numero di argomenti consentiti in Guile: ** config_new_section ** config_new_option ** bar_new ==== Javascript * Le funzioni sono chiamate con `weechat.xxx(arg1, arg2, ...);` ==== PHP * Le funzioni sono chiamate con `weechat_xxx(arg1, arg2, ...);` [[register_function]] === Registrare una funzione Tutti gli script WeeChat devono "registrare" loro stessi in WeeChat, e questo deve essere la prima funzione chiamata nello script di WeeChat. Prototipo: [source,python] ---- weechat.register(name, author, version, license, description, shutdown_function, charset) ---- Argomenti: * _name_: stringa, nome interno dello script * _author_: stringa, nome dell'autore * _version_: stringa, versione dello script * _license_: stringa, licenza dello script * _description_: stringa, breve descrizione dello script * _shutdown_function_: stringa, nome della funzione chiamata quando lo script viene scaricato (può essere una stringa vuota) * _charset_: stringa, set caratteri dello script (se il proprio script è in UTF-8, è possibile utilizzare un valore nullo qui, dato che UTF-8 è il set caratteri predefinito) Esempio di script, per ogni linguaggio: * Python: [source,python] ---- import weechat weechat.register("test_python", "FlashCode", "1.0", "GPL3", "Test script", "", "") weechat.prnt("", "Hello, from python script!") ---- * Perl: [source,perl] ---- weechat::register("test_perl", "FlashCode", "1.0", "GPL3", "Test script", "", ""); weechat::print("", "Hello, from perl script!"); ---- * Ruby: [source,ruby] ---- def weechat_init Weechat.register("test_ruby", "FlashCode", "1.0", "GPL3", "Test script", "", "") Weechat.print("", "Hello, from ruby script!") return Weechat::WEECHAT_RC_OK end ---- * Lua: [source,lua] ---- weechat.register("test_lua", "FlashCode", "1.0", "GPL3", "Test script", "", "") weechat.print("", "Hello, from lua script!") ---- * Tcl: [source,tcl] ---- weechat::register "test_tcl" "FlashCode" "1.0" "GPL3" "Test script" "" "" weechat::print "" "Hello, from tcl script!" ---- * Guile (Scheme): [source,lisp] ---- (weechat:register "test_scheme" "FlashCode" "1.0" "GPL3" "Test script" "" "") (weechat:print "" "Hello, from scheme script!") ---- * Javascript: [source,javascript] ---- weechat.register("test_js", "FlashCode", "1.0", "GPL3", "Test script", "", ""); weechat.print("", "Hello, from javascript script!"); ---- * PHP: [source,php] ---- >). Esempi: [source,python] ---- # visualizza "hello" sul buffer core weechat.prnt("", "hello") # visualizza "hello" sul buffer core, ma non salva sul file di log # (solo versioni >= 0.3.3) weechat.prnt_date_tags("", 0, "no_log", "hello") # visualizza il prefisso "==>" ed il messaggio "hello" sul buffer corrente # (prefisso e messaggio vanno separati da una tabulazione) weechat.prnt(weechat.current_buffer(), "==>\thello") # visualizza un messaggio di errore sul buffer core (con il prefisso di errore) weechat.prnt("", "%swrong arguments" % weechat.prefix("error")) # visualizza messaggio con il colore sul buffer core weechat.prnt("", "text %syellow on blue" % weechat.color("yellow,blue")) # cerca buffer e visualizza messaggiosearch buffer and display message # (il nome completo del buffer è plugin.nome, ad esempio: "irc.freenode.#weechat") buffer = weechat.buffer_search("irc", "freenode.#weechat") weechat.prnt(buffer, "message on #weechat channel") # altra soluzione per cercare un buffer IRC (migliore) # (nota: server e canale sono separati da virgola) buffer = weechat.info_get("irc_buffer", "freenode,#weechat") weechat.prnt(buffer, "message on #weechat channel") ---- [NOTE] La funzione print si chiama `print` in Perl/Ruby/Lua/Tcl/Guile/Javascript e `prnt` in Python. [[buffers_send_text]] ==== Invia testo al buffer È possibile inviare del testo o un comando ad un buffer. È esattamente come se si digitasse del testo o un comando, seguiti da [Enter]. Esempi: // TRANSLATION MISSING [source,python] ---- # execute command "/help" on current buffer (result is on core buffer) weechat.command("", "/help") # invia "hello" sul canale IRC #weechat (gli utenti sul canale vedranno il messaggio) buffer = weechat.info_get("irc_buffer", "freenode,#weechat") weechat.command(buffer, "hello") ---- [[buffers_new]] ==== Creare un nuovo buffer È possibile creare un nuovo buffer nel proprio script, per poi utilizzarlo per visualizzare i messaggi. Possono essere chiamate due callback (sono opzionali): una per i dati in input (quando viene digitato del testo e premuto [Enter] sul buffer), l'altra quando il buffer viene chiuso (ad esempio con `/buffer close`). Esempio: [source,python] ---- # callback per i dati ricevuti in input def buffer_input_cb(data, buffer, input_data): # ... return weechat.WEECHAT_RC_OK # callback chiamata alla chiusura del buffer def buffer_close_cb(data, buffer): # ... return weechat.WEECHAT_RC_OK # crea un buffer buffer = weechat.buffer_new("mybuffer", "buffer_input_cb", "", "buffer_close_cb", "") # imposta titolo weechat.buffer_set(buffer, "title", "Questo titolo è per il mio buffer.") # disabilita il logging, impostando la variabile locale "no_log" ad "1" weechat.buffer_set(buffer, "localvar_set_no_log", "1") ---- [[buffers_properties]] ==== Proprietà dei buffer Si possono leggere le proprietà del buffer, come stringa, intero o puntatore. Esempi: [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") ---- È possibile aggiungere, leggere o eliminare le variabili locali nel buffer: [source,python] ---- # aggiunge la variabile locale weechat.buffer_set(buffer, "localvar_set_myvar", "my_value") # legge la variabile locale myvar = weechat.buffer_get_string(buffer, "localvar_myvar") # elimina la variabile locale weechat.buffer_set(buffer, "localvar_del_myvar", "") ---- Per impostare le variabili locali di un buffer, digitare questo comando in WeeChat: ---- /buffer localvar ---- [[hooks]] === Hook [[hook_command]] ==== Aggiungere un nuovo comando Aggiunge un comando personalizzato con `hook_command`. Si può fare uso di un template di completamento personalizzato per completare gli argomenti del proprio comando. Esempio: [source,python] ---- def my_command_cb(data, buffer, args): # ... return weechat.WEECHAT_RC_OK hook = weechat.hook_command("myfilter", "descrizione di myfilter", "[list] | [enable|disable|toggle [name]] | [add name plugin.buffer tags regex] | [del name|-all]", "descrizione degli argomenti...", "list" " || enable %(filters_names)" " || disable %(filters_names)" " || toggle %(filters_names)" " || add %(filters_names) %(buffers_plugins_names)|*" " || del %(filters_names)|-all", "my_command_cb", "") ---- E poi in WeeChat: ---- /help myfilter /myfilter arguments... ---- [[hook_timer]] ==== Aggiungere un timer Aggiungere un timer con `hook_timer`. Esempio: [source,python] ---- def timer_cb(data, remaining_calls): # ... return weechat.WEECHAT_RC_OK # timer chiamato ogni minuto quandi i secondi sono 00 weechat.hook_timer(60 * 1000, 60, 0, "timer_cb", "") ---- [[hook_process]] ==== Eseguire un processo in background È possibile eseguire un processo in background con `hook_process`. La callback verrà chiamata quando i dati sono pronti. Può essere chiamata più volte. Per l'ultima chiamata alla callback, _rc_ è impostato a zero o su un valore positivo, è il codice restituito dal comando. Esempio: [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]] ==== Trasferimento URL _Novità nella versione 0.3.7._ Per scaricare un URL (o inviare verso un URL), è necessario usare la funzione `hook_process` oppure `hook_process_hashtable` se ci fosse bisogno di impostare delle opzioni per il trasferimento dell'URL. Esempio di trasferimento di un URL senza opzioni: la pagina HTML verrà ricevuta come "out" nella callback (output standard di un processo): [source,python] ---- # Mostra la versione stabile corrente di 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("", "Current WeeChat stable is: %s" % weechat_version) return weechat.WEECHAT_RC_OK weechat.hook_process("url:https://weechat.org/dev/info/stable/", 30 * 1000, "weechat_process_cb", "") ---- [TIP] Tutte le informazioni disponibili su Weechat sono sulla pagina https://weechat.org/dev/info Esempio di trasferimento di un URL con un'opzione: scaricare l'ultimo pacchetto di sviluppo di WeeChat nel file _/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", "") ---- // TRANSLATION MISSING For more information about URL transfer and available options, see functions `hook_process` and `hook_process_hashtable` in link:weechat_plugin_api.it.html#_hook_process[WeeChat plugin API reference]. [[config_options]] === Configurazione / opzioni [[config_options_set_script]] ==== Impostare l'opzione per lo script La funzione `config_is_set_plugin` viene utilizzare per verificare se un'opzione è impostata oppure no, e `config_set_plugin` per impostare l'opzione. Esempio: [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]] ==== Rilevare le modifiche È necessario utilizzare `hook_config` per essere notificati se l'utente dovesse modificare alcune opzioni dello script. Esempio: [source,python] ---- SCRIPT_NAME = "myscript" # ... def config_cb(data, option, value): """Callback called when a script option is changed.""" # for example, read all script options to script variables... # ... return weechat.WEECHAT_RC_OK # ... weechat.hook_config("plugins.var.python." + SCRIPT_NAME + ".*", "config_cb", "") # for other languages, change "python" with your language (perl/ruby/lua/tcl/guile/javascript) ---- [[config_options_weechat]] ==== Leggere le opzioni di WeeChat La funzione `config_get` restituisce il puntatore all'opzione. Poi, in base al tipo di opzione, è necessario chiamare `config_string`, `config_boolean`, `config_integer` oppure `config_color`. [source,python] ---- # stringa weechat.prnt("", "value of option weechat.look.item_time_format is: %s" % (weechat.config_string(weechat.config_get("weechat.look.item_time_format")))) # bool weechat.prnt("", "value of option weechat.look.day_change is: %d" % (weechat.config_boolean(weechat.config_get("weechat.look.day_change")))) # intero weechat.prnt("", "value of option weechat.look.scroll_page_percent is: %d" % (weechat.config_integer(weechat.config_get("weechat.look.scroll_page_percent")))) # colore weechat.prnt("", "value of option weechat.color.chat_delimiters is: %s" % (weechat.config_color(weechat.config_get("weechat.color.chat_delimiters")))) ---- [[irc]] === IRC [[irc_catch_messages]] ==== Catturare messaggi Il plugin IRC invia due segnali per un messaggio ricevuto (`xxx` è il nome interno del server IRC, `yyy` è il nome del comando IRC come JOIN, QUIT, PRIVMSG, 301, ..): xxxx,irc_in_yyy:: segnale inviato prima di esaminare il messaggio xxx,irc_in2_yyy:: segnale inviato dopo aver esaminato il messaggio [source,python] ---- def join_cb(data, signal, signal_data): # signal è per esempio: "freenode,irc_in2_join" # signal_data è il messaggio IRC message, ad esempio: ":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 # può essere utile qui utilizzare "*" come server, per catturare # i messaggi JOIN su tutti i server IRC weechat.hook_signal("*,irc_in2_join", "join_cb", "") ---- [[irc_modify_messages]] ==== Modificare i messaggi Il plugin IRC invia un "modificatore" chiamato "irc_in_xxx" ("xxx" è il comando IRC) per un messaggio ricevuto, in modo da poterlo modificare. [source,python] ---- def modifier_cb(data, modifier, modifier_data, string): # aggiunge il nome del server a tutti i messaggi ricevuti # (ok non è molto utile, ma è solo un esempio!) return "%s %s" % (string, modifier_data) weechat.hook_modifier("irc_in_privmsg", "modifier_cb", "") ---- [WARNING] A malformed message could crash WeeChat or cause severe problems! Un messaggio errato può mandare in crash WeeChat o causare seri problemi! [[irc_message_parse]] ==== Verifica messaggio _Novità nella versione 0.3.4._ È possibile verificare un messaggio irc con una info_hashtable chiamata "irc_message_parse". // TRANSLATION MISSING The result is a hashtable with following keys (the example values are built with this message: `@time=2015-06-27T16:40:35.000Z :nick!user@host PRIVMSG #weechat :hello!`): [width="100%",cols="1,^2,10,8",options="header"] |=== | Key | WeeChat version | Description | Example | tags | ≥ 0.4.0 | The tags in message (can be empty). | `time=2015-06-27T16:40:35.000Z` | message_without_tags | ≥ 0.4.0 | The message without the tags (the same as message if there are no tags). | `:nick!user@host PRIVMSG #weechat :hello!` | nick | ≥ 0.3.4 | The origin nick. | `nick` | host | ≥ 0.3.4 | The origin host (includes the nick). | `nick!user@host` | command | ≥ 0.3.4 | The command (_PRIVMSG_, _NOTICE_, ...). | `PRIVMSG` | channel | ≥ 0.3.4 | The target channel. | `#weechat` | arguments | ≥ 0.3.4 | The command arguments (includes the channel). | `#weechat :hello!` | text | ≥ 1.3 | The text (for example user message). | `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]] === Info [[infos_weechat_version]] ==== Versione di WeeChat Il modo migliore per verificare la versione è richiedere "version_number" e comparare l'intero con il numero di versione esadecimale. Esempio: [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] Le versioni ≤ 0.3.1.1 restituiscono una stringa vuota per _info_get("version_number")_, per cui bisogna verificare che il valore restituito *non* sia vuoto. To get version as string: [source,python] ---- # this will display for example "Version 0.3.2" weechat.prnt("", "Version %s" % weechat.info_get("version", "")) ---- [[infos_other]] ==== Altre informazioni [source,python] ---- # la directory home di WeeChat, ad esempio: "/home/xxxx/.weechat" weechat.prnt("", "WeeChat home dir: %s" % weechat.info_get("weechat_dir", "")) # inattività della tastiera weechat.prnt("", "Inactivity since %s seconds" % weechat.info_get("inactivity", "")) ---- [[infolists]] === Liste info [[infolists_read]] ==== Leggere una lista info È possibile leggere una lista info compilata da WeeChat o da altri plugin. Esempio: [source,python] ---- # legge la lista info "buffer", per ottenere la lista dei buffer 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] Non dimenticare di chiamare `infolist_free` per liberare la memoria utilizzata dalla lista info, perché WeeChat non libererà automaticamente la memoria.