Dobranie odpowiedniego serwera, tak dla skryptu, jak i konta IM nie jest celem tego tutorialu, więc nie wspomnę tutaj w ogóle o jakości i stabilności serwera ****
Gdy przychodzi co do czego, uczeń mistrza Pythona ma do wyboru kilka ostrzy - xmpppy, jakiś python-xmpp z LP, pyxmpp oraz jabber.py. W ciągu ostatniego roku korzystałem chyba z większości z nich, niemniej jednak do tej pory nie wyrobiłem sobie konkretnego zdania na ich temat. Z pewnością python-xmpp z Launchpadu nie jest dobrym wyborem - nie ma określonej licencji.
Do tego "projektu" wybrałem xmpppy - ma całkiem fajną dokumentację.
Jeszcze słówko o założeniach: przy uruchomieniu jak i zmianie godziny, bot ma wysyłać do wszystkich w swoim rosterze wylosowany cytat z bash.org.pl.
Klasa ogólnie będzie miała postać:
class Client: def __init__(self): ... def send_content(self): ...
Na początku zdefiniujmy parę przydatnych zmiennych. Ich znaczenie jest, mniemam, przejrzyste.
class Client: login = "bot" domain = "example.org" password = "abecadlo_z_pieca_spadlo"
Przenieśmy się teraz do metody __init__.
self.jid = xmpp.JID(node=self.login, domain=self.domain, resource="Botownica") self.client = xmpp.Client(server=self.jid.getDomain(), debug=[]) self.client.connect() self.client.auth(self.jid.getNode(), self.password, self.jid.getResource()) self.client.sendInitPresence(True) self.roster = self.client.getRoster()
Cały ten "ogromny" kod odpowiada za połączenie się z serwerem, zalogowanie oraz ustawienie obecności i pobranie listy kontaktów (rostera).
Klasa xmpp.JID nie robi nic ważnego, jest w zasadzie zwykłym pojemnikiem na ustawienia danego konta, jak na przykład login czy zasób. W tym kodzie zasób ustawiliśmy na "Botownica"
Natomiast klasa xmpp.Client jest już ważna. Dziedziczy ona po CommonClient i pomaga ustanowić połączenie szyfrowane (całkiem automagicznie), jak również ułatwia ustawianie obecności.
W następnych liniach łączymy się z serwerem i autentyfikujemy, potem wysyłamy obecność self.client.sendInitPresence(True) - True oznacza, że po zalogowaniu pobrany zostanie roster, który sobie "bierzemy" w ostatniej linii.
file = "bash.txt"
if not os.access(file, os.F_OK):
import urllib2
address = "http://bash.org.pl/text"
data = urllib2.urlopen(address).read()
with open(file, "w") as f:
f.write(data)
if os.access(file, os.R_OK):
self.data = open(file).read()
self.data = self.data.split("%\n")
else:
self.data = []Ostatnie linie w metodzie __init__. Jako że bash.org.pl udostępnia tekstową wersję swoich cytatów, pobieramy ją, ale tylko wtedy, gdy jeszcze pobrana nie została. Dlaczego? Plik waży 1.7MB, przecież nie będzie pobierany co uruchomienie się skryptu.
Gdy uporamy się z pobraniem, staramy się go przeczytać i podzielić na osobne wpisy. Na szczęście są one wszystkie odseparowane przez linię ze znakiem procentu.
Nadszedł czas na metodę send_content, która wysyła do wszystkich w rosterze losowy cytat.
message = random.choice(self.data) for i in self.roster.keys(): if i != self.login+"@"+self.domain: self.client.send(xmpp.protocol.Message(i, message))
W pierwszej linii przypisujemy do message losowy cytat. Następuje pętla przez wszystkie klucze z rostera. Muszę tutaj wytłumaczyć, dlaczego dodałem tego IFa wewnątrz. Otóż, z niewiadomych mi przyczyn, roster przykładowego konta dla mojego bota zawiera sam siebie, dlatego też trzeba go wyfiltrować. Potem zostaje wysłana wiadomość (xmpp.protocol.Message(adresat, treść)) i... To w zasadzie wszystko.
Dodatkowo podam poniżej kod, dzięki któremu co godzinę (a konkretnie co zmianę godziny) będzie wywoływana przed chwilą opisana metoda send_content:
if __name__=="__main__":
c = Client()
try:
c.send_content()
last_hour = time.strftime("%H")
while 1:
if time.strftime("%H")!=last_hour:
c.send_content()
last_hour = time.strftime("%H")
time.sleep(60)
except KeyboardInterrupt as x:
passWażny fragment jest w bloku try: najpierw następuje wysłanie początkowe, tzn. tuż po zalogowaniu. Następnie co minutę, w pętli, sprawdzana jest, i porównywana z dotychczasową, godzina. Jeżeli się zmieniła, to należy wysłać cytaty oraz uaktualnić zmienną last_hour.
Życzę miłej zabawy i eksperymentowania z modułem xmpppy. A nuż powstanie nam powerful klient Jabbera w Pythonie?

Logowanie
Rejestracja
Pomoc

Do góry
Cytuj