PyMSN Python 開發的MSN 模組 (一)基本介紹

安裝可以參考 閃光的 BLOG http://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 如何運作?

搞了半天 這個作者分得太細了(超棒超活用)

原來會話分作兩種

  1. 主動事件 _convo_events(這可以處理 由 程式本身發送出去 所要開啟的會話)
  2. 被動事件 _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()