Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

hmiguel

Python MSN

Mensagens Recomendadas

hmiguel

Alguem conhece alguma biblioteca de msn para python?

Todas as que encontrei tão desactualizadas.  Ainda não consegui usar nenhuma com sucesso.


"Homem que é Homem não usa Java!"

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
IceBrain

Há umas bindings de Python para a libpurple (biblioteca de IM com mais de uma dezena de protocolos), mas acho que são só para Linux: http://developer.pidgin.im/wiki/PythonHowTo

Mas se não precisares de mais do que texto, também podes dar uma volta maior e usar uma biblioteca de IRC para Python, e depois ligares isso ao Bitlbee, que é um gateway IRC -> MSN :confused:


❝The idea that I can be presented with a problem, set out to logically solve it with the tools at hand, and wind up with a program that could not be legally used because someone else followed the same logical steps some years ago and filed for a patent on it is horrifying.❞- John Carmack on software patents

A list  of command line apps

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
djthyrax

Vê as do emesene.


Não peças ajuda por PM! A tua dúvida vai ter menos atenção do que se for postada na secção correcta do fórum!

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
hmiguel

Olá...já tinha visto a possível solução do emessene...o único problema é que o codigo tá todo misturado com gtk,glib,etc...

Mas já encontrei o que pretendia.  :cheesygrin:

Abraço


"Homem que é Homem não usa Java!"

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
hmiguel

Encontrei este bot...não é lib mas é relativamente simples de adaptar.

#!/usr/bin/env python 
# -*- coding: utf-8 -*-

# msnbot.py - connects to MSN Messenger server. Can send and receive messages. 
# 
# futher read about msn protocol:
#  - http://guide.motdlabs.org/edicoes/guide04/MSN_Hacking.
#  - http://www.hypothetic.org/docs/msn/
#
# Bruno Gola 2006-03-10 <brunogola at gmail dot com> [http://www.brunogola.com.br]
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
# 
#
# Please send sugestions/bug reports/fixes/comments/etc to brunogola at gmail dot com.
#
# If you think this tool useful but needs some others features, please send me an email 
#
# TODO: 
# * finish documentation (in english)
##

from socket import socket, ssl, AF_INET, SOCK_STREAM
from sys import exit, stdin, stdout, argv
from os import popen3

import getpass,md5,thread,time,re


class MSN(object):
    """Classe principal"""
    def __init__(self, login, senha):

        self.nome = argv[0]
        self.login = login
        self.senha = senha

        self.host = "messenger.hotmail.com"     # Servidor do messenger
        self.porta = 1863               # Porta padrao
        self._conecta = True

        while self._conecta:    # Loop para tentar conexao, tenta até o usuario desitir :-)
            try: 
                self.conecta()
            
            except KeyboardInterrupt:
                raise KeyboardInterrupt
            except Exception, e:
                print e
                esc = raw_input("<o> Erro na conexao, tentar novamente [Y/n]? ")
                if esc.lower() == "n" :
                    self._conecta = False
                    self._sair(0)
    
    def conecta(self):
        request = "VER 1 MSNP9 MSNP10\r\n"   # Esse request eh o responsavel por pedir a conexao
        
        # criamos o socket que vai conectar
        self.sock = socket(AF_INET, SOCK_STREAM)
        self.sock.connect((self.host, self.porta))
        print "\n>>> Conectando (%s:%s)" % (self.host, self.porta)
        buffer_resp = self.envia_request(request)
        
        # Se houver algum erro na conexao o servidor retorna essa mensagem (protocolo)
        if buffer_resp == "VER 1 0\r\n": 
            print """<<< Desconectado do servidor, talvez a versão falhou.
                     Persistindo o erro tente atualizar o %s.""" %self.nome
            self._sair(1)

        # É aqui que informamos para o servidor nosso so, conta, etc. No request utilizado 
        # informamos que estamos usando linux 2.6.16 para arquitetura i386 e o cliente é 
        # o MSN Messenger da MS, versão 7.0
        request = "CVR 2 0x0409 linux 2.6.16 i386 MSMSGR 7.0 MSMSGR %s\r\n" % self.login
        buffer_resp = self.envia_request(request)
      
        request = "USR 3 TWN I %s\r\n" % self.login
        print ">>> Enviando username (%s)" % self.login
        buffer_resp = self.envia_request(request)
    
        buffer_resp_split = buffer_resp.split()
        if buffer_resp_split[0] == "XFR":    # Conectar ao server indicado
            print buffer_resp
            foo = buffer_resp_split[3].split(':')
            self.host = foo[0] # novo servidor
            self.porta = int(foo[1]) # nova porta
            # Volta pro while em __init__ e tenta conectar no novo host/porta.
            print ">>> Redirecionando para o servidor %s:%d" % (self.host,self.porta) 
            self.sock.close()                                  
    
        elif buffer_resp_split[0] == "USR":  # Conexao feita com sucesso, iniciando autenticacao
            print buffer_resp
            print "<o> Autenticando no MS Passport"
            self.string_auth = buffer_resp
            auth = str(MSNPassport(self)) # Cria um MSNPassport e envia para o servidor a key mostrando que estamos autenticados
            
            if auth:
                print "<o> Autenticado, ticket: %s" % auth
                # FIM Autenticacao            

            buffer_resp = self.envia_request(auth)
            self._conecta = False
            #try:
            print "<o> Robo logado com sucesso... entrando em modo online"
            self.startListener() #parte pro listener, o robo mesmo.
            #except:
            #   self._sair(1)
        
        else:
            print "<o> Erro desconhecido"
            self.sock.close()
            self._conecta = False
            self._sair(1)
    
    # Envia um request e retorna uma possivel resposta do servidor
    def envia_request(self,request):
        self.sock.send(request)
        buffer_retorno = self.sock.recv(1024)
        return buffer_retorno

    def _sair(self,signal):  
        try: 
            self.sock.close()    # Tenta matar uma possivel conexao
        except:
            pass
        print "Obrigado por usar o %s" % self.nome
        exit(signal)

    def startListener(self):
        listener = MSNListener(self)


class MSNListener(object):
    """Controla tudo que vier de informação do servidor do messenger, desde notificações de login, logout, challenges e tudo mais, porém, só vai tratar o que nos interessar."""
    def __init__(self, msn):
        #self.conversas = [] # Armazenaremos as conversas ativas em uma lista
        self.ncontatos = None
        self.nickname = ""
        self.sock = msn.sock
        self.msn = msn
        self.msn.contatos = [] # Contatos
        request = "CHG 12 NLN 0\r\n"
        self.sock.send(request)
        buffer_resp = self.sock.recv(2048)
        #buffer_resp = self.msn.envia_request(request)
        buffer_send = "SYN 4 0 0\r\n"
        self.sock.send(buffer_send)
        c_count = 0
        while 1:
            buffer_resp = self.sock.recv(2048)
            #stdout.write("Teste\n")
            #stdout.write(buffer_resp)
            #stdout.flush()
            if "CHL" == buffer_resp[:3]: # challenge
                print "Respondendo um ping do server..."
                message = buffer_resp.split(' ')[2][:-2]
                message += "Q1P7W2E4J9R8U3S5"
                message = md5.new(message).hexdigest()
                request = "QRY 1049 msmsgs@msnmsgr.com 32\r\n%s" % message
                self.sock.send(request)
                self.sock.recv(2048)
            
            elif buffer_resp.startswith("SYN "):
                self.ncontatos = int(buffer_resp.rsplit(None, 2)[1])
            elif re.match(".*PRP MFN.*",buffer_resp.replace("\n","")): # nick
                self.nickname = buffer_resp.split('MFN')[1][1:].replace("%20"," ")
                #print self.nickname
            
            elif "RNG" == buffer_resp[:3]: # alguem quer conversar
                msg = buffer_resp.split(' ')
                self.info_contato = {     
                'host': msg[2].split(':')[0],
                'porta': int(msg[2].split(':')[1]),
                'auth': msg[4],
                'ID': msg[1],
                'login': msg[5] }
                thread.start_new_thread(self.aceita_conversa,())
                print "Iniciando conversa..."
            
            elif "XFR" == buffer_resp[:3] and re.match(".*SB.*",buffer_resp.replace("\n","")): # conversa
                self.info_sb = {
                'host': msg[3].split(':')[0],
                'porta': int(msg[3].split(':')[1]),
                'auth': msg[5],}
                thread.start_new_thread(self.inicia_sb,())

            elif buffer_resp[:3] == "LST": # and re.match(".*N=.*",buffer_resp): # lista contatos
                contato = buffer_resp.split(" ")[1].replace("N=","")
                self.msn.contatos.append(contato)
                c_count += 1
            if c_count == self.ncontatos:
                print self.msn.contatos
            #else: 
                #stdout.write(buffer_resp)
                #stdout.flush()
                #time.sleep(.2)
                #pass
    def aceita_conversa(self): # alguem quer conversar, inicia a conversa
        sock = socket(AF_INET,SOCK_STREAM)            
        sock.connect((self.info_contato['host'], self.info_contato['porta'])) 
        request = "ANS 1 %s %s %s\r\n" % (self.msn.login,self.info_contato['auth'],self.info_contato['ID'])
        sock.send(request)
        stdout.write("Conversa criada...\n")
        stdout.flush()
        conversa = MSNConversa(self,sock)
    
    def inicia_sb(self):
        sock = socket(AF_INET,SOCK_STREAM)            
        sock.connect((self.info_sb['host'], self.info_sb['porta'])) 
        request = "USR 1 %s %s\r\n" % (self.msn.login,self.info_sb['auth'])
        sock.send(request)

#   def convida_contato(self,cotato,sb)
    
    
class MSNConversa(object):
    """Conversa, recebe mensagens e notificacoes numa seção de chat.
Envia mensagens para a conversa tambem."""
    def __init__(self,listener,sock):
        self.destroy = False
        self.sock = sock
        self.listener = listener
        self.msn = listener.msn
        self.nickname = listener.nickname
        self.info = self.listener.info_contato
        stdout.write("MSNConversa")
        stdout.flush()
        self.sendMSG("Ola %s :-), \nexecute algum comando para testar minha interface :-)\nDuvidas? Tente '!help'" % self.info['login']) 
        while not self.destroy:    
            buffer_req = self.sock.recv(2048)
            if "ANS" == buffer_req[:3] and re.match(".*OK.*",buffer_req.replace("\n","")):    # Confirmacao de conversa
                msg_conversa = "Conversa iniciada com -> %s\n" % self.info['login']
                stdout.write(msg_conversa)
                stdout.flush()
        
            elif re.match(".*text/plain.*",buffer_req.replace("\n","")):    # Mensagem de texto
                msg_incoming = buffer_req.split("\r\n\r\n")[1:]
                msg_in = "%s -> " % (self.info['login'])
                msg_in_a = ""
                for i in msg_incoming:
                    msg_in_a += i
                    msg_in += msg_in_a+"\r\n\r\n"
                    stdout.write(msg_in[:-2]) 
                    stdout.flush()
                cmd = popen3(msg_in_a)
                r_ok = cmd[1].read()
                r_failed = cmd[2].read()
                r_failed = "Comando invalido ou uso errado, erro do S.O. :\n"+r_failed
                if msg_in_a[:6] == "!help":
                    self.sendMSG("Use comandos do S.O.")
                elif not r_ok and msg_in_a[:4] != "cd ":
                    self.sendMSG(r_failed)
                else:
                    self.sendMSG(r_ok)
            elif re.match(".*BYE.*", buffer_req.replace("\n","")):            # Saiu da conversa
                msg_close = "%s saiu da conversa.\n" % self.info['login']
                stdout.write(msg_close)
                stdout.flush()
                self._destroy()
                
    def _destroy(self):
        self.sock.close()
        self.destroy = True
        thread.exit_thread()

    def sendMSG(self,mensagem):
        buffer_msg = 'MIME-Version: 1.0\r\nContent-Type: text/x-msmsgscontrol\r\nTypingUser: '+self.info['login']+'\r\n\r\n\r\n'
        buffer_msg_header = "MSG 2 N %d\r\n" % len(buffer_msg)
        buffer_msg = buffer_msg_header+buffer_msg
        self.sock.send(buffer_msg)
        buffer_msg = 'MIME-Version: 1.0\r\nContent-Type: text/plain; charset=UTF-8\r\nX-MMS-IM-Format: FN=MS%20Sans%20Serif; EF=; CO=0; CS=0; PF=0\r\n\r\n'+mensagem
        buffer_msg_header = "MSG 3 U %d\r\n" % len(buffer_msg)
        buffer_msg = buffer_msg_header+buffer_msg
        self.sock.send(buffer_msg)
        

class MSNPassport(object): 
    """Classe para o MSN Passport, faz a conexao via SSL e autentica contra o servidor passport do MSN."""
    def __init__(self,msn):
        self.sock = socket(AF_INET,SOCK_STREAM)
        self.sock.connect(('nexus.passport.com',443))  # Conexao HTTPS.
    
        ssl_conn = ssl(self.sock)    # Iniciamos a conexao SSL, para autenticacao segura
        request = "GET /rdr/pprdr.asp HTTP/1.0\r\n\r\n"
        ssl_conn.write(request)         # Envia o GET acima
        
        # Le a resposta do servidor para o request enviado
        # nessa reposta esta o server que devemos usar para
        # continuar com a autenticacao 
        buffer_passport = ssl_conn.read()     
        
        # Pega o ip do proximo nó para completar a autenticação
        passport_host = buffer_passport.split("DALogin=")[1].split(',')[0].split('/')[0]
        passport_port = 443

        self.sock.close()
    
        self.sock = socket(AF_INET,SOCK_STREAM)        
        self.sock.connect((passport_host,passport_port))  # conectamos no servidor indicado
        ssl_conn = ssl(self.sock)
    
        string = msn.string_auth.split("TWN")[1].split()[1]
        username = msn.login.split("@")
        buffer_passport = "GET /login2.srf HTTP/1.0\r\n\r\nAuthorization: Passport1.4 OrgVerb=GET,OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=" + username[0] + "%40" + username[1] + ",pwd=" + msn.senha + "," + string + "\r\n\r\nHost: " + passport_host + "\r\n\r\n"  
    
        ssl_conn.write(buffer_passport)
        buffer_passport = ssl_conn.read()
    
        tmp = buffer_passport.split("Location:")
        buffer_passport = tmp[1].split()
        location = buffer_passport[0].split("?")
    
        self.sock.close()
    
        # Verificamos o dominio do username para saber onde autenticar
        if username[1] == "hotmail.com" or username[1] == "msn.com": 
            server = "loginnet.passport.com"
        else:
            server = "login.passport.com"
    
        self.sock = socket(AF_INET,SOCK_STREAM)
        self.sock.connect((server,443))
        ssl_conn = ssl(self.sock)
        buffer_passport = "GET /login2.srf HTTP/1.1\r\nAuthorization: Passport1.4 OrgVerb=GET,"+ \
                          "OrgURL=http%3A%2F%2Fmessenger%2Emsn%2Ecom,sign-in=" + username[0] + \
                          "%40" + username[1] + ",pwd=" + msn.senha + "," + string + \
                          "\r\nHost: login.passport.com\r\n\r\n"
        ssl_conn.write(buffer_passport)
        buffer_passport = ssl_conn.read(2024)
        if buffer_passport.split(" ")[1] != "200":
            print "<<< Erro na aquisicao do Passport, senha/usuario errado(s) ?"
            exit(1)
        tmp = buffer_passport.split("from-PP='")
        buffer_passport = tmp[1].split("',ru=")
        self.ticket = buffer_passport[0]
        self.ticket = "USR 4 TWN S " + self.ticket + "\r\n"
        
        self.sock.close()

    def __str__(self):
        return self.ticket
    
if __name__ == "__main__":
    
    if len(argv) < 2:
        print "Uso: %s [e-mail] <senha>" % argv[0]
        exit(0)

    usuario = argv[1]
    if len(argv) == 3:
        senha = argv[2]
    else:
        senha = getpass.getpass("Digite a senha para %s: " % usuario)

    try:
        m = MSN(usuario,senha)
    except KeyboardInterrupt:
        print "Ctrl+C, saindo..."
        exit(0)

Créditos mantidos!


"Homem que é Homem não usa Java!"

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.