Correction and editing of the tutorials.
[100%] English version [100%] Polish version [100%] Both version consistency check [98 %] Final sanity check + formating
This commit is contained in:
parent
9fd8684c5a
commit
f84bfce5f3
@ -1,13 +1,13 @@
|
||||
Jak stworzyć własny plugin rozszerzający obiekty Message i Iq w Slixmpp
|
||||
====================================================================
|
||||
========================================================================
|
||||
|
||||
Wstęp i wymagania
|
||||
-----------------
|
||||
------------------
|
||||
|
||||
* `'python3'`
|
||||
|
||||
Kod użyty w tutorialu jest kompatybilny z pythonem w wersji 3.6 lub nowszej.
|
||||
Dla wstecznej kompatybilności z wcześniejszymi wersjami należy zastąpić f-strings starszym formatowaniem napisów `'"{}".format("content")'` lub `'%s, "content"'`.
|
||||
Dla uzyskania kompatybilności z wcześniejszymi wersjami należy zastąpić f-strings starszym formatowaniem napisów `'"{}".format("content")'` lub `'%s, "content"'`.
|
||||
|
||||
Instalacja dla Ubuntu linux:
|
||||
|
||||
@ -62,11 +62,10 @@ Jeśli jakaś biblioteka zwróci NameError, należy zainstalować pakiet ponowni
|
||||
* `Konta dla Jabber`
|
||||
|
||||
Do testowania niezbędne będą dwa prywatne konta jabbera. Można je stworzyć na jednym z dostępnych darmowych serwerów:
|
||||
|
||||
https://www.google.com/search?q=jabber+server+list
|
||||
|
||||
Skrypt uruchamiający klientów
|
||||
-----------------------------
|
||||
------------------------------
|
||||
|
||||
Skrypt pozwalający testować klientów powinien zostać stworzony poza lokalizacją projektu. Pozwoli to szybko sprawdzać wyniki skryptów oraz uniemożliwi przypadkowe wysłanie swoich danych na gita.
|
||||
|
||||
@ -132,7 +131,7 @@ Skrypt uruchamiający powinien być dostosowany do potrzeb urzytkownika: można
|
||||
W przypadku testowania większych aplikacji, w tworzeniu pluginu szczególnie użyteczne jest nadanie unikalnych nazwy dla każdego klienta (w konsekwencji: różne linie poleceń). Pozwala to szybko określić, który klient co zwraca, bądź który powoduje błąd.
|
||||
|
||||
Stworzenie klienta i pluginu
|
||||
----------------------------
|
||||
-----------------------------
|
||||
|
||||
W stosownej dla nas lokalizacji powinniśmy stworzyć dwa klienty slixmpp (w przykładach: `'sender'` i `'responder'`), aby sprawdzić czy skrypt uruchamiający działa poprawnie. Poniżej przedstawiona została minimalna niezbędna implementacja, która może testować plugin w trakcie jego projektowania:
|
||||
|
||||
@ -158,10 +157,10 @@ W stosownej dla nas lokalizacji powinniśmy stworzyć dwa klienty slixmpp (w prz
|
||||
|
||||
self.add_event_handler("session_start", self.start)
|
||||
|
||||
def start(self, event):
|
||||
# Dwie niewymagane metody pozwalające innym użytkownikom zobaczyć dostępność online.
|
||||
self.send_presence()
|
||||
self.get_roster()
|
||||
def start(self, event):
|
||||
# Dwie niewymagane metody pozwalające innym użytkownikom zobaczyć dostępność online.
|
||||
self.send_presence()
|
||||
self.get_roster()
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = ArgumentParser(description=Sender.__doc__)
|
||||
@ -268,7 +267,7 @@ Następny plik, który należy stworzyć to `'example_plugin'`. Powinien być w
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
#File: $WORKDIR/example/example plugin.py
|
||||
#File: $WORKDIR/example/example_plugin.py
|
||||
import logging
|
||||
|
||||
from slixmpp.xmlstream import ElementBase, ET, register_stanza_plugin
|
||||
@ -395,7 +394,7 @@ Aby otrzymać tę wiadomość, responder powinien wykorzystać odpowiedni event:
|
||||
#<<<<<<<<<<<<
|
||||
|
||||
Rozszerzenie Message o nowy tag
|
||||
-------------------------
|
||||
--------------------------------
|
||||
|
||||
Aby rozszerzyć obiekt Message o wybrany tag, plugin powinien zostać zarejestrowany jako rozszerzenie dla obiektu Message:
|
||||
|
||||
@ -455,7 +454,7 @@ Teraz, po rejestracji tagu, można rozszerzyć wiadomość.
|
||||
# Default mtype == "chat";
|
||||
msg = self.make_message(mto=to, mbody=body)
|
||||
#>>>>>>>>>>>>
|
||||
msg['example_tag'].set_some_string("Work!")
|
||||
msg['example_tag']['some_string'] = "Work!"
|
||||
logging.info(msg)
|
||||
#<<<<<<<<<<<<
|
||||
msg.send()
|
||||
@ -463,7 +462,7 @@ Teraz, po rejestracji tagu, można rozszerzyć wiadomość.
|
||||
Po uruchomieniu, logging powinien wyświetlić Message wraz z tagiem `'example_tag'` zawartym w środku <message><example_tag/></message>, oraz z napisem `'Work'` i nadanym namespace.
|
||||
|
||||
Nadanie oddzielnego sygnału dla rozszerzonej wiadomości
|
||||
-------------------------
|
||||
--------------------------------------------------------
|
||||
|
||||
Jeśli event nie zostanie sprecyzowany, to zarówno rozszerzona jak i podstawowa wiadomość będą przechwytywane przez sygnał `'message'`. Aby nadać im oddzielny event, należy zarejestrować odpowiedni handler dla namespace'a i tagu, aby stworzyć unikalną kombinację, która pozwoli na przechwycenie wyłącznie pożądanych wiadomości (lub Iq object).
|
||||
|
||||
@ -556,12 +555,12 @@ Można odesłać wiadomość, ale nic się nie stanie jeśli to nie zostanie zro
|
||||
Natomiast obiekt komunikacji (Iq) już będzie wymagał odpowiedzi, więc obydwaj klienci powinni pozostawać online. W innym wypadku, klient otrzyma automatyczny error z powodu timeoutu, jeśli cell Iq nie odpowie za pomocą Iq o tym samym Id.
|
||||
|
||||
Użyteczne metody i inne
|
||||
-----------------------
|
||||
------------------------
|
||||
|
||||
Modyfikacja przykładowego obiektu `Message` na obiekt `Iq`
|
||||
-------------------------
|
||||
----------------------------------------------------------
|
||||
|
||||
Aby przerobić przykładowy obiekt Message na obiekt Iq, należy zarejestrować nowy handler dla Iq, podobnie jak zostało to przedstawione w rozdziale `"Rozszerzenie Message o tag"`. Tym razem, przykład będzie zawierał kilka rodzajów Iq o oddzielnych typami. Poprawia to czytelność kodu oraz usprawnia weryfikację poprawności działania. Wszystkie Iq powinny odesłać odpowiedź z tym samym Id i odpowiedzią do wysyłającego. W przeciwnym wypadku, wysyłający dostanie Iq zwrotne typu error, zawierające informacje o przekroczonym czasie oczekiwania (timeout).
|
||||
Aby przerobić przykładowy obiekt Message na obiekt Iq, należy zarejestrować nowy handler dla Iq, podobnie jak zostało to przedstawione w rozdziale `,,Rozszerzenie Message o tag''`. Tym razem, przykład będzie zawierał kilka rodzajów Iq o oddzielnych typami. Poprawia to czytelność kodu oraz usprawnia weryfikację poprawności działania. Wszystkie Iq powinny odesłać odpowiedź z tym samym Id i odpowiedzią do wysyłającego. W przeciwnym wypadku, wysyłający dostanie Iq zwrotne typu error.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -765,7 +764,7 @@ Kiedy odpowiednie gettery i settery są tworzone, można sprawdzić, czy na pewn
|
||||
iq.send()
|
||||
|
||||
Wczytanie ExampleTag ElementBase z pliku XML, łańcucha znaków i innych obiektów
|
||||
-------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
Jest wiele możliwości na wczytanie wcześniej zdefiniowanego napisu z pliku albo lxml (ElementTree). Poniższy przykład wykorzystuje parsowanie typu tekstowego do lxml (ElementTree) i przekazanie atrybutów.
|
||||
|
||||
@ -882,7 +881,7 @@ Do przetestowania tej funkcjonalności, potrzebny jest pliku zawierający xml z
|
||||
Jeśli Responder zwróci wysłane Iq, a Sender wyłączy się po trzech odpowiedziach, wtedy wszystko działa tak, jak powinno.
|
||||
|
||||
Łatwość użycia pluginu dla programistów
|
||||
--------------------------------------
|
||||
----------------------------------------
|
||||
|
||||
Każdy plugin powinien posiadać pewne obiektowe metody: wczytanie danych, jak w przypadku metod `setup` z poprzedniego rozdziału, gettery, settery, czy wywoływanie odpowiednich eventów.
|
||||
Potencjalne błędy powinny być przechwytywane z poziomu pluginu i zwracane z odpowiednim opisem błędu w postaci odpowiedzi Iq o tym samym id do wysyłającego. Aby uniknąć sytuacji kiedy plugin nie robi tego co powinien, a wiadomość zwrotna nigdy nie nadchodzi, wysyłający dostaje error z komunikatem timeout.
|
||||
@ -1238,7 +1237,7 @@ Poniżej przykład kodu podyktowanego tymi zasadami:
|
||||
|
||||
|
||||
Tagi i atrybuty zagnieżdżone wewnątrz głównego elementu
|
||||
--------------------------------------
|
||||
---------------------------------------------------------
|
||||
|
||||
Aby stworzyć zagnieżdżony tag, wewnątrz głównego tagu, rozważmy atrybut `'self.xml'` jako Element z ET (ElementTree). W takim wypadku, aby stworzyć zagnieżdżony element można użyć funkcji 'append'.
|
||||
|
||||
@ -1790,7 +1789,7 @@ W poniższym kodzie zostały pozostawione oryginalne komentarze w języku angiel
|
||||
<example_tag xmlns="https://example.net/our_extension" some_string="StringFromFile">Info_inside_tag<inside_tag first_field="3" secound_field="4" /></example_tag>
|
||||
|
||||
Źródła i bibliogarfia
|
||||
---------------------
|
||||
----------------------
|
||||
|
||||
Slixmpp - opis projektu:
|
||||
|
||||
@ -1804,4 +1803,4 @@ Oficjalna dokumentacja PDF:
|
||||
|
||||
* https://buildmedia.readthedocs.org/media/pdf/slixmpp/latest/slixmpp.pdf
|
||||
|
||||
Note: Dokumentacje w formie Web i PDF różnią się; pewne szczegóły potrafią być wspomniane tylko w jednej z dwóch.
|
||||
Dokumentacje w formie Web i PDF różnią się; pewne szczegóły potrafią być wspomniane tylko w jednej z dwóch.
|
||||
|
@ -2,7 +2,7 @@ How to make a slixmpp plugins for Messages and IQ extensions
|
||||
====================================================================
|
||||
|
||||
Introduction and requirements
|
||||
-----------------
|
||||
------------------------------
|
||||
|
||||
* `'python3'`
|
||||
|
||||
@ -21,7 +21,7 @@ Ubuntu linux installation steps:
|
||||
* `'subprocess'`
|
||||
* `'threading'`
|
||||
|
||||
Check if these libraries and the proper python version are available at your environment. Every one of these, except the slixmpp, is a standard python library. However, it may happened that some of them may not be installed.
|
||||
Check if these libraries and the proper python version are available at your environment. Every one of these, except the slixmpp, is a standard python library. However, it may happen that some of them may not be installed.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -62,8 +62,7 @@ If some of the libraries throws NameError, reinstall the whole package once agai
|
||||
* `Jabber accounts`
|
||||
|
||||
For the testing purposes, two private jabber accounts are required. They can be created on one of many available sites:
|
||||
|
||||
[https://www.google.com/search?q=jabber+server+list](https://www.google.com/search?q=jabber+server+list)
|
||||
https://www.google.com/search?q=jabber+server+list
|
||||
|
||||
Client launch script
|
||||
-----------------------------
|
||||
@ -129,12 +128,12 @@ The `'subprocess.run()'`function is compatible with Python 3.5+. If the backward
|
||||
|
||||
The launch script should be convenient in use and easy to reconfigure again. The proper preparation of it now, can help saving time in the future. Logging credentials, the project paths (from `'sys.argv[...]'` or `'os.getcwd()'`), set the parameters for the debugging purposes, mock the testing xml file and many more things can be defined inside. Whichever parameters are used, the script testing itself should be fast and effortless. The proper preparation of it now, can help saving time in the future.
|
||||
|
||||
In case of manually testing the larger applications, it would be a good practise to introduce the unique names (consequently, different commands) for each client. In case of any errors, it will be easier to find the client that caused it.
|
||||
In case of manually testing the larger applications, it would be a good practice to introduce the unique names (consequently, different commands) for each client. In case of any errors, it will be easier to find the client that caused it.
|
||||
|
||||
Creating the client and the plugin
|
||||
----------------------------
|
||||
-----------------------------------
|
||||
|
||||
Two slimxmpp clients should be created in order to check if everything works correctly (here: the `'sender'` and the `'responder'`). The minimal amount of code needed for effective building and testing of the plugin is the following:
|
||||
Two slixmpp clients should be created in order to check if everything works correctly (here: the `'sender'` and the `'responder'`). The minimal amount of code needed for effective building and testing of the plugin is the following:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -158,10 +157,10 @@ Two slimxmpp clients should be created in order to check if everything works cor
|
||||
|
||||
self.add_event_handler("session_start", self.start)
|
||||
|
||||
def start(self, event):
|
||||
# Two, not required methods, but allows another users to see if the client is online.
|
||||
self.send_presence()
|
||||
self.get_roster()
|
||||
def start(self, event):
|
||||
# Two, not required methods, but allows another users to see if the client is online.
|
||||
self.send_presence()
|
||||
self.get_roster()
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = ArgumentParser(description=Sender.__doc__)
|
||||
@ -264,11 +263,11 @@ Two slimxmpp clients should be created in order to check if everything works cor
|
||||
except:
|
||||
pass
|
||||
|
||||
Next file to create is `'example_plugin.py'`. It can be placed in the same catalogue as the clients, so the problems with unknown paths can be avoided.
|
||||
Next file to create is `'example_plugin.py'`. It can be placed in the same folder as the clients, so the problems with unknown paths can be avoided.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
#File: $WORKDIR/example/example plugin.py
|
||||
#File: $WORKDIR/example/example_plugin.py
|
||||
import logging
|
||||
|
||||
from slixmpp.xmlstream import ElementBase, ET, register_stanza_plugin
|
||||
@ -330,9 +329,9 @@ The `'def start(self, event):'` method should look like this:
|
||||
If everything works fine, this line can be commented out.
|
||||
|
||||
Building the message object
|
||||
-------------------------
|
||||
------------------------------
|
||||
|
||||
The example sender class should get a recipient name and address (jid of responder) from command line arguments, stored in test_slixmpp. An access to this argument is stored in the `'self.to'`attribute.
|
||||
The example sender class should get a recipient name and address (jid of responder) from command line arguments, stored in test_slixmpp. An access to this argument is stored in the `'self.to'` attribute.
|
||||
|
||||
Code example:
|
||||
|
||||
@ -395,7 +394,7 @@ To receive this message, the responder should have a proper handler to the signa
|
||||
#<<<<<<<<<<<<
|
||||
|
||||
Expanding the Message with a new tag
|
||||
-------------------------
|
||||
-------------------------------------
|
||||
|
||||
To expand the Message object with a tag, the plugin should be registered as the extension for the Message object:
|
||||
|
||||
@ -455,7 +454,7 @@ Now, with the registered object, the message can be extended.
|
||||
# Default mtype == "chat";
|
||||
msg = self.make_message(mto=to, mbody=body)
|
||||
#>>>>>>>>>>>>
|
||||
msg['example_tag'].set_some_string("Work!")
|
||||
msg['example_tag']['some_string'] = "Work!"
|
||||
logging.info(msg)
|
||||
#<<<<<<<<<<<<
|
||||
msg.send()
|
||||
@ -463,7 +462,7 @@ Now, with the registered object, the message can be extended.
|
||||
After running, the logging should print the Message with tag `'example_tag'` stored inside <message><example_tag/></message>, string `'Work'` and given namespace.
|
||||
|
||||
Giving the extended message the separate signal
|
||||
-------------------------
|
||||
------------------------------------------------
|
||||
|
||||
If the separate event is not defined, then both normal and extended message will be cached by signal `'message'`. In order to have the special event, the handler for the namespace and tag should be created. Then, make a unique name combination, which allows the handler can catch only the wanted messages (or Iq object).
|
||||
|
||||
@ -556,12 +555,12 @@ The messages can be replied, but nothing will happen otherwise.
|
||||
The Iq object, on the other hand, should always be replied. Otherwise, the error occurs on the client side due to the target timeout if the cell Iq won't reply with Iq with the same Id.
|
||||
|
||||
Useful methods and misc.
|
||||
-----------------------
|
||||
|
||||
Modifying the example `Message` object to the `Iq` object
|
||||
-------------------------
|
||||
|
||||
To convert the Message into the Iq object, a new handler for the Iq should be registered, in the same manner as in the `,,Extend message with tags''`part. The following example contains several types of Iq different types to catch. It can be used to check the difference between the Iq request and Iq response or to verify the correctness of the objects. All of the Iq messages should be passed to the sender with the same ID parameter, otherwise the sender receives the Iq with the timeout error.
|
||||
Modifying the example `Message` object to the `Iq` object
|
||||
----------------------------------------------------------
|
||||
|
||||
To allow our custom element into Iq payloads, a new handler for Iq can be registered, in the same manner as in the `,,Extend message with tags''` part. The following example contains several types of Iq different types to catch. It can be used to check the difference between the Iq request and Iq response or to verify the correctness of the objects. All of the Iq messages should be passed to the sender with the same ID parameter, otherwise the sender will receive an error message.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -687,7 +686,7 @@ By default, the parameter `'clear'` in the `'Iq.reply'` is set to True. In that
|
||||
#<<<<<<<<<<<<
|
||||
|
||||
Different ways to access the elements
|
||||
-------------------------
|
||||
--------------------------------------
|
||||
|
||||
There are several ways to access the elements inside the Message or Iq stanza. The first one: the client can access them like a dictionary:
|
||||
|
||||
@ -765,7 +764,7 @@ When the proper setters and getters are used, it is easy to check whether some a
|
||||
iq.send()
|
||||
|
||||
Message setup from the XML files, strings and other objects
|
||||
-------------------------
|
||||
------------------------------------------------------------
|
||||
|
||||
There are many ways to set up a xml from a string, xml-containing file or lxml (ElementTree) file. One of them is parsing the strings to lxml object, passing the attributes and other information, which may look like this:
|
||||
|
||||
@ -1263,7 +1262,7 @@ As shown in the previous examples, it is possible to create a new element as mai
|
||||
There is a way to do this with a dictionary and name for the nested element tag. In that case, the insides of the function fields should be transferred to the ET element.
|
||||
|
||||
Complete code from tutorial
|
||||
-------------------------
|
||||
----------------------------
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@ -1787,7 +1786,7 @@ Complete code from tutorial
|
||||
<example_tag xmlns="https://example.net/our_extension" some_string="StringFromFile">Info_inside_tag<inside_tag first_field="3" second_field="4" /></example_tag>
|
||||
|
||||
Sources and references
|
||||
---------------------
|
||||
-----------------------
|
||||
|
||||
The Slixmpp project description:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user