Привет %habrauser%! Это мой первый хабротопик. В котором я расскажу как можно сделать ICQ бот на pythone. Бот у нас будет сидеть в сети и отправлять, по запросу пользователя, список последних статей хабра.
Для реализации бота мы будем использовать библиотеку Twisted. Конечно же есть уже специализированные библиотеки для работы с ICQ на python. Такие как py-icq или nanoicq. Но так как с Twisted я был уже знаком, то выбор пал именно на него.
Дабы не изобретать велосипед, возьмем львиную часть программы из примера:
Тут начальная часть у нас и заканчивается. Загрузим необходимые библиотеки.
Feedparser нам нужен для того чтобы стянуть и отпарсить rss ленту хабры. Теперь сам бот. Тут почти все от примера, за исключением мелких изменений…
Тут-то у нас самая вкусная часть. Обработка входящих сообщений:
Первая команда у нас будет !habr, но тут есть небольшие исключения. Если команда синтаксиса !habr n, то будет выведено последние n постов. Если же команда синтаксиса !habr n1 n2, то с n1 по n2 постов ( мой маленький каприз ). Конечно же вывод ограничен 20-ю постами, т.к. в xml страничке их именно 20.
Команда !habrn n будет выводить содержимое поля description поля n
Тут то я хочу упомянуть про import urllib2, который я вписал в начало. Порой мне нужно узнать ip моего домашнего сервера, дабы зайти на него по ssh. Ну и конечно же не хотелось бы чтобы его адрес знал кто либо другой.
Если заглянуть на http://api.wipmania.com/, то можно обнаружить довольно таки простую html страничку на которой будет наш внешний ip.
Ну и заключительная часть:
Вот и все. Хочу сказать спасибо человеку, помогшему получить ip для последней команды.
Вот весь код:
Спасибо за внимание!
Для реализации бота мы будем использовать библиотеку Twisted. Конечно же есть уже специализированные библиотеки для работы с ICQ на python. Такие как py-icq или nanoicq. Но так как с Twisted я был уже знаком, то выбор пал именно на него.
Дабы не изобретать велосипед, возьмем львиную часть программы из примера:
- # UIN
- UIN = "" #Наш уин
- PASS = "" #Соответственно пароль
- host = ("login.icq.com", 5238) # Сервер/порт
- icqMode = 1
- # Status message
- AMSG = "I'm here +)"
* This source code was highlighted with Source Code Highlighter.
Тут начальная часть у нас и заканчивается. Загрузим необходимые библиотеки.
- from twisted.words.protocols import oscar
- from twisted.internet import protocol, reactor
- import feedparser
- import urllib2 #Прошу не забивать голову пока этим. Для чего это, расскажу чуть позже
* This source code was highlighted with Source Code Highlighter.
Feedparser нам нужен для того чтобы стянуть и отпарсить rss ленту хабры. Теперь сам бот. Тут почти все от примера, за исключением мелких изменений…
- # Class Bot
- class Bot(oscar.BOSConnection):
- capabilities = [oscar.CAP_CHAT]
- def initDone(self):
- print "Connect ",UIN," to server", host[0], host[1]
- self.requestSelfInfo().addCallback(self.gotSelfInfo)
- self.requestSSI().addCallback(self.gotBuddyList)
- self.setAway(AMSG)
- def gotSelfInfo(self, user):
- print user.__dict__
- self.name = user.name
- def gotBuddyList(self, l):
- print l
- self.activateSSI()
- self.setProfile("""ICQBot""")
- self.setIdleTime(0)
- self.clientReady()
- def gotAway(self, away, user):
- if away:
- print "User ", user,": ",away
* This source code was highlighted with Source Code Highlighter.
Тут-то у нас самая вкусная часть. Обработка входящих сообщений:
- def receiveMessage(self, user, multiparts, flags):
- print "\n< From: ", user.name
- print "< Message: ", multiparts[0][0].decode('cp1251')
- command = multiparts[0][0].lower().split(' ') #разбиваем сообщение по пробелам
- PREF_C = "!" #команды у нас будут начинаться с !
* This source code was highlighted with Source Code Highlighter.
Первая команда у нас будет !habr, но тут есть небольшие исключения. Если команда синтаксиса !habr n, то будет выведено последние n постов. Если же команда синтаксиса !habr n1 n2, то с n1 по n2 постов ( мой маленький каприз ). Конечно же вывод ограничен 20-ю постами, т.к. в xml страничке их именно 20.
- if command[0] == (PREF_C+"habr"):
- rss = feedparser.parse('http://habrahabr.ru/rss')#забираем xml страничку и парсим
- feeds = [0,20] #Это у нас для дополнительного функционала )
- if len(command) == 2:
- try:
- feeds[1] = int(command[1])
- except:
- feeds[1] = 0
- if feeds[1]<1: feeds[1] = 1
- if feeds[1]>20: feeds[1] = 20
- elif len(command) == 3:
- try:
- feeds[0] = int(command[1])-1
- feeds[1] = int(command[2])
- except:
- feeds[0] = 0
- feeds[1] = 19
- if feeds[0]<0: feeds[0] = 0
- if feeds[0]>19: feeds[0] = 19
- if feeds[1]<1: feeds[1] = 1
- if feeds[1]>20: feeds[1] = 20
- mes = ''
- for feed in range(feeds[0],feeds[1]):
- mes += rss.entries[feed].title+'\n'
- self.sendMessage(user.name, mes)
* This source code was highlighted with Source Code Highlighter.
Команда !habrn n будет выводить содержимое поля description поля n
- elif command[0] == (PREF_C+"habrn"):
- rss = feedparser.parse('http://habrahabr.ru/rss')
- try:
- feedn = int(command[1])-1
- except:
- feedn = 0
- if feedn<0: feedn = 0
- if feedn>19: feedn = 19
- self.sendMessage(user.name, rss.entries[feedn].title+'\n'+rss.entries[feedn].description)
* This source code was highlighted with Source Code Highlighter.
Тут то я хочу упомянуть про import urllib2, который я вписал в начало. Порой мне нужно узнать ip моего домашнего сервера, дабы зайти на него по ssh. Ну и конечно же не хотелось бы чтобы его адрес знал кто либо другой.
- elif command[0] == (PREF_C+"ip") and user.name == '368576236':
- file_s = urllib2.urlopen(urllib2.Request('http://api.wipmania.com/'))
- response = file_s.read()
- self.sendMessage(user.name, response.split("<br>")[0])
- f.close()
* This source code was highlighted with Source Code Highlighter.
Если заглянуть на http://api.wipmania.com/, то можно обнаружить довольно таки простую html страничку на которой будет наш внешний ip.
Ну и заключительная часть:
- class BotAuth(oscar.OscarAuthenticator):
- BOSClass = Bot
- protocol.ClientCreator(reactor, BotAuth, UIN, PASS, icq=icqMode).connectTCP(*host)
- reactor.run()
* This source code was highlighted with Source Code Highlighter.
Вот и все. Хочу сказать спасибо человеку, помогшему получить ip для последней команды.
Вот весь код:
- # -*- coding: utf-8 -*-
- # ICQ bot
-
- # UIN
- UIN = "123456"
- PASS = "pass"
-
-
- # Server
- host = ("login.icq.com", 5238)
- icqMode = 1
-
- # Status message
- AMSG = "I'm here +)"
-
- from twisted.words.protocols import oscar
- from twisted.internet import protocol, reactor
- import feedparser
- import urllib2
-
- # Class Bot
- class Bot(oscar.BOSConnection):
-
- capabilities = [oscar.CAP_CHAT]
-
- def initDone(self):
- print "Connect ",UIN," to server", host[0], host[1]
-
- self.requestSelfInfo().addCallback(self.gotSelfInfo)
- self.requestSSI().addCallback(self.gotBuddyList)
-
- self.setAway(AMSG)
-
- def gotSelfInfo(self, user):
- print user.__dict__
- self.name = user.name
-
-
- def gotBuddyList(self, l):
- print l
- self.activateSSI()
- self.setProfile("""ICQBot""")
- self.setIdleTime(0)
- self.clientReady()
-
- def gotAway(self, away, user):
- if away:
- print "User ", user,": ",away
-
- def receiveMessage(self, user, multiparts, flags):
- print "\n< From: ", user.name
- print "< Message: ", multiparts[0][0].decode('cp1251')
- command = multiparts[0][0].lower().split(' ')
-
-
- PREF_C = "!"
- if command[0] == (PREF_C+"habr"):
- rss = feedparser.parse('http://habrahabr.ru/rss')
- feeds = [0,20]
- if len(command) == 2:
- try:
- feeds[1] = int(command[1])
- except:
- feeds[1] = 0
-
- if feeds[1]<1: feeds[1] = 1
- if feeds[1]>20: feeds[1] = 20
-
- elif len(command) == 3:
- try:
- feeds[0] = int(command[1])-1
- feeds[1] = int(command[2])
- except:
- feeds[0] = 0
- feeds[1] = 19
-
- if feeds[0]<0: feeds[0] = 0
- if feeds[0]>19: feeds[0] = 19
- if feeds[1]<1: feeds[1] = 1
- if feeds[1]>20: feeds[1] = 20
-
- mes = ''
- for feed in range(feeds[0],feeds[1]):
- mes += rss.entries[feed].title+'\n'
-
- self.sendMessage(user.name, mes)
-
-
- elif command[0] == (PREF_C+"habrn"):
- rss = feedparser.parse('http://habrahabr.ru/rss')
- try:
- feedn = int(command[1])-1
- except:
- feedn = 0
- if feedn<0: feedn = 0
- if feedn>19: feedn = 19
-
- self.sendMessage(user.name, rss.entries[feedn].title+'\n'+rss.entries[feedn].description)
-
-
- elif command[0] == (PREF_C+"ip") and user.name == '123456':
- file_s = urllib2.urlopen(urllib2.Request('http://api.wipmania.com/'))
- response = file_s.read()
- self.sendMessage(user.name, response.split("<br>")[0])
- f.close()
-
- class BotAuth(oscar.OscarAuthenticator):
- BOSClass = Bot
-
- protocol.ClientCreator(reactor, BotAuth, UIN, PASS, icq=icqMode).connectTCP(*host)
- reactor.run()
* This source code was highlighted with Source Code Highlighter.
Спасибо за внимание!