POSTS
PyMSN Python 開發的MSN 模組 (一)基本介紹
安裝可以參考 閃光的 BLOG https://blog.hinablue.me/794
基本使用介紹:
- 使用命令列執行 可以加 2個參數 1.帳號 2.密碼 EXAMPLE:python test.py aaaa@hotmail 123123123
- Log可自行調配 是否輸出存檔
- 在使用任何 套件模組 像這種依照物件下去設計的 千萬不要改原始碼(等改版 你就知道痛了)
- 這邊 一開始如果用 預設的範例test.py你會遇到 傳訊息沒回應或出現event_handler 等等error.(稍後會講解)
原理分析:
一開始會依照ClientEvents 這個CLASS去動作 這裡的CODE 寫了 當連線後正常 每5秒一次 執行 start_conversation 這個物件
start_conversation 這就是主要動作物件可以在這邊加入 聯絡人新增 連戀人狀態變更等等事件用法
最重要的來了 會話conversation 如何運作?
搞了半天 這個作者分得太細了(超棒超活用)
原來會話分作兩種
- 主動事件 _convo_events(這可以處理 由 程式本身發送出去 所要開啟的會話)
- 被動事件 _invite_handler(這可以處理 由 發送人發送給程式 所要開啟的會話)
而且一開始會搞不懂 我門主動開啟會話之後還沒有辦法處理 收到的訊息 這原因是因為 那個事件只是當下被處理 馬上又離開事件
變成應該要去 被動事件那邊 作反向處理才是 作接收端回應~
感謝收看 我很不會表達
#!/usr/bin/env python
# coding: utf-8
# -*- coding: utf-8 -*-
import os, sys
import pymsn
import pymsn.event
import md5
import logging
import gobject
if sys.getdefaultencoding() != 'utf-8':
reload(sys)
sys.setdefaultencoding('utf-8')
logging.basicConfig(filename = os.path.join(os.getcwd(), 'log.txt'),level=logging.DEBUG)#基本LOG設定存檔
#logging.basicConfig(level=logging.DEBUG) #基本LOG設定不存檔
finished = False
def get_proxies():
import urllib
proxies = urllib.getproxies()
result = {}
if 'https' not in proxies and \
'http' in proxies:
url = proxies['http'].replace("http://", "https://")
result['https'] = pymsn.Proxy(url)
for type, url in proxies.items():
if type == 'no': continue
if type == 'https' and url.startswith('http://'):
url = url.replace('http://', 'https://', 1)
result[type] = pymsn.Proxy(url)
return result
class ClientEvents(pymsn.event.ClientEventInterface):
def on_client_state_changed(self, state):
if state == pymsn.event.ClientState.CLOSED:#當連線關閉時離開結束
self._client.quit()
elif state == pymsn.event.ClientState.OPEN:#當連線成立時
self._client.profile.display_name = "SDpowerMSN"
self._client.profile.presence = pymsn.Presence.ONLINE
#self._client.profile.current_media = ("我正在搞", "大蛇")
for contact in self._client.address_book.contacts:
print contact
self._client.profile.personal_message = "我正在搞大蛇!"
gobject.timeout_add(5000, self._client.start_conversation)
def on_client_error(self, error_type, error):
print "ERROR :", error_type, " ->", error
class Invite(pymsn.event.InviteEventInterface):#開起會話的事件
def on_invite_conversation(self, conversation):
self._conversation = AnnoyingConversation(conversation)#起始會話物件
class AnnoyingConversation(pymsn.event.ConversationEventInterface):#我自訂會話物件
def on_conversation_user_joined(self, contact):#開啟會話
print "有人來哩~",contact
def on_conversation_state_changed(self, state):#會話狀態變更
print "state_change :",state
def on_conversation_user_left(self, contact):#離開
print "user_left :",contact.display_name
def on_conversation_user_typing(self, contact):#誰誰 正在打字
print "%s inizia a scrivere" % contact.display_name
def on_conversation_message_received(self, sender, message):#收到 訊息
self._client.send_typing_notification()#送出 正在打字
msg = "你說:" + message.content #回送訊息
formatting = pymsn.TextFormat("微軟正黑體",
pymsn.TextFormat.UNDERLINE | pymsn.TextFormat.BOLD,
'FF0000')
self._client.send_text_message(pymsn.ConversationMessage(msg, formatting))
def on_conversation_nudge_received(self, sender):#收到叮咚
msg = "喔喔好晃喔~ 搖大鼻要在晃哩 :P"
formatting = pymsn.TextFormat("微軟正黑體",
pymsn.TextFormat.UNDERLINE | pymsn.TextFormat.BOLD,
'FF0000')
self._client.send_text_message(pymsn.ConversationMessage(msg, formatting))
def on_conversation_error(self, error_type, error):
print "ERROR :", error_type, " ->", error
class Client(pymsn.Client):#基本起始 MSN物件
def __init__(self, account, quit, http_mode=False):
server = ('messenger.hotmail.com', 1863)
self.quit = quit
self.account = account
if http_mode:
from pymsn.transport import HTTPPollConnection
pymsn.Client.__init__(self, server, get_proxies(), HTTPPollConnection)
else:
pymsn.Client.__init__(self, server, proxies = get_proxies())
self._event_handler = ClientEvents(self)#重要 起始送出會話物件
self._invite_handler = Invite(self)#重要 起始邀請會話物件
gobject.idle_add(self._connect)
def _connect(self):
self.login(*self.account)
return False
def start_conversation(self):#自行定義的 當連線成功後所執行的區塊
contacts = self.address_book.contacts
if len(contacts) == 0:
print "No online contacts"
return True
def main():
import sys
import getpass
import signal
if "--http" in sys.argv:
http_mode = True
sys.argv.remove('--http')
else:
http_mode = False
if len(sys.argv) < 2:
account = raw_input('Account: ')
else:
account = sys.argv[1]
if len(sys.argv) < 3:
passwd = getpass.getpass('Password: ')
else:
passwd = sys.argv[2]
mainloop = gobject.MainLoop(is_running=True)
def quit():
mainloop.quit()
def sigterm_cb():
gobject.idle_add(quit)
signal.signal(signal.SIGTERM, sigterm_cb)
n = Client((account, passwd), quit, http_mode)
while mainloop.is_running():
try:
mainloop.run()
except KeyboardInterrupt:
quit()
if __name__ == '__main__':
main()