Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # -*- coding: utf- 8 -*-
- try:
- version = 'git ' + open(os.path.join(os.path.dirname(__file__), '.git/refs/heads/master')).read().strip()
- except:
- version = 'unknown'
- import os, signal, sys, time, traceback, xmpp
- import config, xmlconfig
- import json, urllib, urllib2
- import threading
- from xmpp.browser import *
- class MyHandler(urllib2.HTTPHandler):
- def http_response(self, req, response):
- return response
- class Transport:
- online = 1
- restart = 0
- offlinemsg = ''
- def __init__(self,jabber):
- self.jabber = jabber
- self.mappings = [mapping.split('=') for mapping in config.domains]
- def register_handlers(self):
- self.jabber.RegisterHandler('message',self.xmpp_message)
- self.jabber.RegisterHandler('presence',self.xmpp_presence)
- self.disco = Browser()
- self.disco.PlugIn(self.jabber)
- self.disco.setDiscoHandler(self.xmpp_base_disco,node='',jid=config.jid)
- # Disco Handlers
- def xmpp_base_disco(self, con, event, type):
- fromjid = event.getFrom().__str__()
- to = event.getTo()
- node = event.getQuerynode();
- #Type is either 'info' or 'items'
- if to == config.jid:
- if node == None:
- if type == 'info':
- return {
- 'ids':[
- {'category':'gateway','type':'smtp','name':config.discoName}],
- 'features':[NS_VERSION,NS_COMMANDS]}
- if type == 'items':
- return []
- else:
- self.jabber.send(Error(event,ERR_ITEM_NOT_FOUND))
- raise NodeProcessed
- else:
- self.jabber.send(Error(event,MALFORMED_JID))
- raise NodeProcessed
- #XMPP Handlers
- def xmpp_presence(self, con, event):
- # Add ACL support
- fromjid = event.getFrom()
- type = event.getType()
- to = event.getTo()
- if type == 'subscribe':
- self.jabber.send(Presence(to=fromjid, frm = to, typ = 'subscribe'))
- elif type == 'subscribed':
- self.jabber.send(Presence(to=fromjid, frm = to, typ = 'subscribed'))
- elif type == 'unsubscribe':
- self.jabber.send(Presence(to=fromjid, frm = to, typ = 'unsubscribe'))
- elif type == 'unsubscribed':
- self.jabber.send(Presence(to=fromjid, frm = to, typ = 'unsubscribed'))
- elif type == 'probe':
- self.jabber.send(Presence(to=fromjid, frm = to))
- elif type == 'unavailable':
- self.jabber.send(Presence(to=fromjid, frm = to, typ = 'unavailable'))
- elif type == 'error':
- return
- else:
- self.jabber.send(Presence(to=fromjid, frm = to))
- def xmpp_message(self, con, event):
- # print "Outgoing event. Hello, bluronair!"
- type = event.getType()
- fromjid = event.getFrom()
- msg_from = fromjid.getStripped()
- msg_to = event.getTo()
- msg_body = event.getBody()
- cid = None
- handler = None
- arg1 = None
- arg2 = None
- # здесь будет обработка гейта для отсылки смс.
- # determine caller id
- for mapping in self.mappings:
- if mapping[1] == msg_from:
- cid = mapping[0]
- handler = mapping[2]
- arg1 = mapping[3]
- arg2 = mapping[4]
- # if cid empty
- if not arg1:
- logstr = "[ERROR] Cannot determine send handler for jid [%s]." % msg_from
- logAppend(logstr)
- return
- # determine phonenum to
- to_arr = msg_to.__str__().split("@")
- to = to_arr[0]
- # send
- msg = urllib.quote_plus(msg_body.encode('utf-8'))
- url = "http://%s?secret=%s&action=sendSms&cid=%s&to=%s&msg=%s&handler=%s&arg1=%s&arg2=%s" % (config.apiServer, config.apiSecret, cid, to, msg, handler, arg1, arg2)
- handler = urllib2.build_opener(MyHandler())
- thread = threading.Thread(target=handler.open, args=(url,))
- thread.start()
- thread.join()
- logstr = "[INFO] [%s] with CallerID [%s] has sent message to [%s]" % (msg_from, cid, to)
- logAppend(logstr)
- # messtr = "Ваше сообщение успешно отправлено на [%s]. Результат: [%s]" % (to, answer)
- # print "to %s from %s body %s" % (msg_from, msg_to, messtr)
- # mes = Message(to = msg_from, frm = msg_to, body = messtr, typ = "chat")
- # self.jabber.send(mes)
- def mail_check(self):
- if time.time() < self.lastcheck + 5:
- return
- self.lastcheck = time.time()
- url = "http://%s?secret=%s&action=getEvents" % (config.apiServer, config.apiSecret)
- request = urllib2.urlopen(url)
- answer = request.read()
- messages = json.loads(answer)
- if not messages:
- return
- for sms in messages:
- jfrom = "%s@%s" % (sms["from_num"], config.jid)
- jto = None
- # determine jTo
- for mapping in self.mappings:
- if mapping[0] == sms["to_num"]:
- jto = mapping[1]
- # continue if mapping not found
- if not jto:
- logstr = "[ERROR] Cannot route incoming message for [%s]: no route for this number." % sms["to_num"]
- logAppend(logstr)
- continue
- # msg?
- body = sms["message"]
- # send
- m = Message(to = jto, frm = jfrom, body = body, typ = "chat")
- if self.jabber.send(m):
- logstr = "[INFO] New message for [%s] from [%s]: routed to [%s]" % (sms["to_num"], sms["from_num"], jto)
- logAppend(logstr)
- # delivery report
- url = "http://%s?secret=%s&action=markAsRead&id=%s" % (config.apiServer, config.apiSecret, sms["id"])
- urllib2.urlopen(url)
- else:
- logstr = "[ERROR] Cannot deliver message for [%s] from [%s]: routed to [%s]" % (sms["to_num"], sms["from_num"], jto)
- logAppend(logstr)
- def xmpp_connect(self):
- connected = self.jabber.connect((config.mainServer,config.port))
- if config.dumpProtocol: print "connected:",connected
- while not connected:
- time.sleep(5)
- connected = self.jabber.connect((config.mainServer,config.port))
- if config.dumpProtocol: print "connected:",connected
- self.register_handlers()
- if config.dumpProtocol: print "trying auth"
- connected = self.jabber.auth(config.saslUsername,config.secret)
- if config.dumpProtocol: print "auth return:",connected
- return connected
- def xmpp_disconnect(self):
- time.sleep(5)
- if not self.jabber.reconnectAndReauth():
- time.sleep(5)
- self.xmpp_connect()
- def loadConfig():
- configOptions = {}
- for configFile in config.configFiles:
- if os.path.isfile(configFile):
- xmlconfig.reloadConfig(configFile, configOptions)
- config.configFile = configFile
- return
- print "Configuration file not found. You need to create a config file and put it in one of these locations:\n " + "\n ".join(config.configFiles)
- sys.exit(1)
- def logError():
- err = '%s - %s\n'%(time.strftime('%a %d %b %Y %H:%M:%S'),version)
- #if logfile != None:
- # logfile.write(err)
- # traceback.print_exc(file=logfile)
- # logfile.flush()
- sys.stderr.write(err)
- traceback.print_exc()
- sys.exc_clear()
- def logAppend(logmsg):
- toLog = '[%s] %s\n' % (time.strftime('%a %d %b %Y %H:%M:%S'),logmsg)
- if logfile != None:
- logfile.write(toLog)
- logfile.flush()
- def sigHandler(signum, frame):
- transport.offlinemsg = 'Signal handler called with signal %s'%signum
- if config.dumpProtocol: print 'Signal handler called with signal %s'%signum
- transport.online = 0
- if __name__ == '__main__':
- if 'PID' in os.environ:
- config.pid = os.environ['PID']
- loadConfig()
- if config.pid:
- pidfile = open(config.pid,'w')
- pidfile.write(`os.getpid()`)
- pidfile.close()
- if config.saslUsername:
- sasl = 1
- else:
- config.saslUsername = config.jid
- sasl = 0
- logfile = None
- if config.debugFile:
- logfile = open(config.debugFile,'a')
- if config.dumpProtocol:
- debug=['always', 'nodebuilder']
- else:
- debug=[]
- connection = xmpp.client.Component(config.jid,config.port,debug=debug,sasl=sasl,bind=config.useComponentBinding,route=config.useRouteWrap)
- transport = Transport(connection)
- if not transport.xmpp_connect():
- print "Could not connect to server, or password mismatch!"
- sys.exit(1)
- logAppend("Connection successfully established.")
- # Set the signal handlers
- signal.signal(signal.SIGINT, sigHandler)
- signal.signal(signal.SIGTERM, sigHandler)
- transport.lastcheck = time.time() + 10
- while transport.online:
- try:
- connection.Process(1)
- transport.mail_check()
- except KeyboardInterrupt:
- _pendingException = sys.exc_info()
- raise _pendingException[0], _pendingException[1], _pendingException[2]
- except IOError:
- transport.xmpp_disconnect()
- except:
- logError()
- if not connection.isConnected(): transport.xmpp_disconnect()
- connection.disconnect()
- if config.pid:
- os.unlink(config.pid)
- if logfile:
- logfile.close()
- if transport.restart:
- args=[sys.executable]+sys.argv
- if os.name == 'nt': args = ["\"%s\"" % a for a in args]
- if config.dumpProtocol: print sys.executable, args
- os.execv(sys.executable, args)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement