diff --git a/daemon.py b/daemon.py index c762c70..90cade9 100755 --- a/daemon.py +++ b/daemon.py @@ -4,154 +4,154 @@ from signal import SIGTERM class Daemon: - """ - A generic daemon class. - Usage: subclass the Daemon class and override the run() method - """ - ''' - Modified by Tread Soft for yowsup-daemon. - ''' - def __init__(self, pidfile, out): - path=os.getcwd() - self.stdin = 'dev/null' - if out==True: - self.stdout =os.getcwd()+'/out' - else: - self.stdout='dev/null' - self.stderr = os.getcwd()+'/err.log' - self.pidfile = pidfile - - def daemonize(self): - """ - do the UNIX double-fork magic, see Stevens' "Advanced - Programming in the UNIX Environment" for details (ISBN 0201563177) - http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 - """ - try: - pid = os.fork() - if pid > 0: - # exit first parent - sys.exit(0) - except OSError, e: - sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) - sys.exit(1) - - # decouple from parent environment - os.chdir("/") - os.setsid() - os.umask(0) - - # do second fork - try: - pid = os.fork() - if pid > 0: - # exit from second parent - sys.exit(0) - except OSError, e: - sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) - sys.exit(1) - - # redirect standard file descriptors - sys.stdout.flush() - sys.stderr.flush() - si = file(self.stdin, 'r') - so = file(self.stdout, 'a+') - se = file(self.stderr, 'a+', 0) - os.dup2(si.fileno(), sys.stdin.fileno()) - os.dup2(so.fileno(), sys.stdout.fileno()) - os.dup2(se.fileno(), sys.stderr.fileno()) - - # write pidfile - atexit.register(self.delpid) - pid = str(os.getpid()) - file(self.pidfile,'w+').write("%s\n" % pid) - - def delpid(self): - os.remove(self.pidfile) - def status(self): + """ + A generic daemon class. + Usage: subclass the Daemon class and override the run() method + """ + ''' + Modified by Tread Soft for yowsup-daemon. + ''' + def __init__(self, pidfile, out): + path=os.getcwd() + self.stdin = 'dev/null' + if out==True: + self.stdout =os.getcwd()+'/out' + else: + self.stdout='dev/null' + self.stderr = os.getcwd()+'/err.log' + self.pidfile = pidfile + + def daemonize(self): + """ + do the UNIX double-fork magic, see Stevens' "Advanced + Programming in the UNIX Environment" for details (ISBN 0201563177) + http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 + """ + try: + pid = os.fork() + if pid > 0: + # exit first parent + sys.exit(0) + except OSError as e: + sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) + sys.exit(1) + + # decouple from parent environment + os.chdir("/") + os.setsid() + os.umask(0) + + # do second fork + try: + pid = os.fork() + if pid > 0: + # exit from second parent + sys.exit(0) + except OSError as e: + sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) + sys.exit(1) + + # redirect standard file descriptors + sys.stdout.flush() + sys.stderr.flush() + si = open(self.stdin, 'r') + so = open(self.stdout, 'a+') + se = open(self.stderr, 'a+', 1) + os.dup2(si.fileno(), sys.stdin.fileno()) + os.dup2(so.fileno(), sys.stdout.fileno()) + os.dup2(se.fileno(), sys.stderr.fileno()) + + # write pidfile + atexit.register(self.delpid) + pid = str(os.getpid()) + open(self.pidfile,'w+').write("%s\n" % pid) + + def delpid(self): + os.remove(self.pidfile) + def status(self): - try: - pf=file(self.pidfile,'r') - pid=int(pf.read().strip()) - pf.close() - except IOError: - pid=None - - if pid: - message="Daemon running\n" - sys.stderr.write(message ) - sys.exit(1) - else: - message="Daemon not running\n" - sys.stderr.write(message ) - sys.exit(1) + try: + pf=open(self.pidfile,'r') + pid=int(pf.read().strip()) + pf.close() + except IOError: + pid=None + + if pid: + message="Daemon running\n" + sys.stderr.write(message ) + sys.exit(1) + else: + message="Daemon not running\n" + sys.stderr.write(message ) + sys.exit(1) - def start(self): - """ - Start the daemon - """ - # Check for a pidfile to see if the daemon already runs - - try: - pf = file(self.pidfile,'r') - pid = int(pf.read().strip()) - pf.close() + def start(self): + """ + Start the daemon + """ + # Check for a pidfile to see if the daemon already runs + + try: + pf = open(self.pidfile,'r') + pid = int(pf.read().strip()) + pf.close() - except IOError: - pid = None - - if pid: - message = "Pidfile %s already exists. Daemon already running?\n" - sys.stderr.write(message % self.pidfile) - sys.exit(1) - - # Start the daemon - print "Daemon starting. Check output in out and errors in err.log" - self.daemonize() - self.run() - def nodaemon(self): - self.run() - def stop(self): - """ - Stop the daemon - """ - # Get the pid from the pidfile - try: - pf = file(self.pidfile,'r') - pid = int(pf.read().strip()) - pf.close() - print "Daemon stopped." - except IOError: - pid = None - - if not pid: - message = "pidfile %s does not exist. Daemon not running?\n" - sys.stderr.write(message % self.pidfile) - return # not an error in a restart + except IOError: + pid = None + + if pid: + message = "Pidfile %s already exists. Daemon already running?\n" + sys.stderr.write(message % self.pidfile) + sys.exit(1) + + # Start the daemon + print ("Daemon starting. Check output in out and errors in err.log") + self.daemonize() + self.run() + def nodaemon(self): + self.run() + def stop(self): + """ + Stop the daemon + """ + # Get the pid from the pidfile + try: + pf = open(self.pidfile,'r') + pid = int(pf.read().strip()) + pf.close() + print ("Daemon stopped.") + except IOError: + pid = None + + if not pid: + message = "pidfile %s does not exist. Daemon not running?\n" + sys.stderr.write(message % self.pidfile) + return # not an error in a restart - # Try killing the daemon process - try: - while 1: - os.kill(pid, SIGTERM) - time.sleep(0.1) - except OSError, err: - err = str(err) - if err.find("No such process") > 0: - if os.path.exists(self.pidfile): - os.remove(self.pidfile) - else: - print str(err) - sys.exit(1) + # Try killing the daemon process + try: + while 1: + os.kill(pid, SIGTERM) + time.sleep(0.1) + except OSError as err: + err = str(err) + if err.find("No such process") > 0: + if os.path.exists(self.pidfile): + os.remove(self.pidfile) + else: + print (str(err)) + sys.exit(1) - def restart(self): - """ - Restart the daemon - """ - self.stop() - self.start() + def restart(self): + """ + Restart the daemon + """ + self.stop() + self.start() - def run(self): - """ - You should override this method when you subclass Daemon. It will be called after the process has been - daemonized by start() or restart(). - """ + def run(self): + """ + You should override this method when you subclass Daemon. It will be called after the process has been + daemonized by start() or restart(). + """ diff --git a/layer.py b/layer.py index e8ce236..f64b08d 100755 --- a/layer.py +++ b/layer.py @@ -1,80 +1,80 @@ -from yowsup.layers.interface import YowInterfaceLayer, ProtocolEntityCallback -from yowsup.layers.protocol_messages.protocolentities import TextMessageProtocolEntity -from yowsup.layers.protocol_receipts.protocolentities import OutgoingReceiptProtocolEntity -from yowsup.layers.protocol_acks.protocolentities import OutgoingAckProtocolEntity +from yowsup.layers.interface import YowInterfaceLayer, ProtocolEntityCallback +from yowsup.layers.protocol_messages.protocolentities import TextMessageProtocolEntity +from yowsup.layers.protocol_receipts.protocolentities import OutgoingReceiptProtocolEntity +from yowsup.layers.protocol_acks.protocolentities import OutgoingAckProtocolEntity import subprocess import threading import time import sys, os class DaemonLayer(YowInterfaceLayer): - dic={} - allowshell=False - dictStart=False - allowed=[] - - def initialize(self,path): - with open(path+'/config.cfg') as f: - for line in f: - if line.find('Command dictionary',1)==1: - self.dictStart=True - elif line.find('allowed',0,7)==0: - self.allowed.append(line[9:20]) - elif not line.find('allow_direct_shell',0)==-1: - self.allowshell=True - if self.dictStart and not line.find(':',0)==-1: - self.dic[line.split(':',1)[0]]=line.split(':',1)[1] + dic={} + allowshell=False + dictStart=False + allowed=[] + + def initialize(self,path): + with open(path+'/config.cfg') as f: + for line in f: + if line.find('Command dictionary',1)==1: + self.dictStart=True + elif line.find('allowed',0,7)==0: + self.allowed.append(line[9:20]) + elif not line.find('allow_direct_shell',0)==-1: + self.allowshell=True + if self.dictStart and not line.find(':',0)==-1: + self.dic[line.split(':',1)[0]]=line.split(':',1)[1] - @ProtocolEntityCallback("message") - def onMessage(self, messageProtocolEntity): - #send receipt otherwise we keep receiving the same message over and over - if True: - receipt = OutgoingReceiptProtocolEntity(messageProtocolEntity.getId(), messageProtocolEntity.getFrom()) - self.toLower(receipt) - order = messageProtocolEntity.getBody() - print 'Message received from: ' +messageProtocolEntity.getFrom()[0:11] - print 'On: ' + time.strftime('%d-%m-%Y %H:%M:%S') - print order - if not messageProtocolEntity.getFrom()[23:24]=='g': - if messageProtocolEntity.getBody() in self.dic or messageProtocolEntity.getBody()[0:6]=="Shell:": - if messageProtocolEntity.getFrom()[0:11] in self.allowed: - order = messageProtocolEntity.getBody() - if order[0:6]=="Shell:": - if self.allowshell: - order=order[7:] - else: - order="echo No permitido" - else: - order=self.dic[order] - p=subprocess.Popen(order,stdout=subprocess.PIPE,shell=True) - (output,err)=p.communicate() - p_status=p.wait() - order=output[:-1] - else: - order="Lo siento no tienes permiso para ejecutar ordenes." - else: - order='No te he entendido' - - outgoingMessageProtocolEntity=TextMessageProtocolEntity(order,to=messageProtocolEntity.getFrom()) - self.toLower(outgoingMessageProtocolEntity) - else: - print "group message" + @ProtocolEntityCallback("message") + def onMessage(self, messageProtocolEntity): + #send receipt otherwise we keep receiving the same message over and over + if True: + receipt = OutgoingReceiptProtocolEntity(messageProtocolEntity.getId(), messageProtocolEntity.getFrom()) + self.toLower(receipt) + order = messageProtocolEntity.getBody() + print ('Message received from: ' +messageProtocolEntity.getFrom()[0:11]) + print ('On: ' + time.strftime('%d-%m-%Y %H:%M:%S')) + print (order) + if not messageProtocolEntity.getFrom()[23:24]=='g': + if messageProtocolEntity.getBody() in self.dic or messageProtocolEntity.getBody()[0:6]=="Shell:": + if messageProtocolEntity.getFrom()[0:11] in self.allowed: + order = messageProtocolEntity.getBody() + if order[0:6]=="Shell:": + if self.allowshell: + order=order[7:] + else: + order="echo No permitido" + else: + order=self.dic[order] + p=subprocess.Popen(order,stdout=subprocess.PIPE,shell=True) + (output,err)=p.communicate() + p_status=p.wait() + order=output[:-1] + else: + order="Lo siento no tienes permiso para ejecutar ordenes." + else: + order='No te he entendido' + + outgoingMessageProtocolEntity=TextMessageProtocolEntity(order,to=messageProtocolEntity.getFrom()) + self.toLower(outgoingMessageProtocolEntity) + else: + print ("group message") - @ProtocolEntityCallback("receipt") - def onReceipt(self, entity): - ack = OutgoingAckProtocolEntity(entity.getId(), "receipt", "delivery") - self.toLower(ack) + @ProtocolEntityCallback("receipt") + def onReceipt(self, entity): + ack = OutgoingAckProtocolEntity(entity.getId(), "receipt", "delivery") + self.toLower(ack) - ''' - @ProtocolEntityCallback("ack") - def onAck (self, entiy): - self.lock.acquire() - if entity.getId() in self.ackQueue: - self.ackQueue.pop(self.ackQueue.index(entity.getId())) + ''' + @ProtocolEntityCallback("ack") + def onAck (self, entiy): + self.lock.acquire() + if entity.getId() in self.ackQueue: + self.ackQueue.pop(self.ackQueue.index(entity.getId())) - if not len(self.ackQueue): - self.lock.release() - raise KeyboardInterrupt - - self.lock.release - ''' + if not len(self.ackQueue): + self.lock.release() + raise KeyboardInterrupt + + self.lock.release + ''' diff --git a/send.py b/send.py index c4590bd..87d1530 100755 --- a/send.py +++ b/send.py @@ -1,25 +1,25 @@ #!/usr/bin/env python from yowsup.demos import sendclient -from yowsup import env +from yowsup import env import sys,time,os import logging logging.basicConfig(level=logging.ERROR) if len(sys.argv)!=3: - print 'Usage: %s phone_number message' %sys.argv[0] - sys.exit(0) + print ('Usage: %s phone_number message' %sys.argv[0]) + sys.exit(0) with open(os.path.dirname(os.path.realpath(sys.argv[0]))+'/config.cfg') as f: - for line in f: - if line.find('phone number:',0)==0: - phone=line[13:] - phone=phone.strip() - elif line.find('password:',0)==0: - passwd=line[9:].strip() + for line in f: + if line.find('phone number:',0)==0: + phone=line[13:] + phone=phone.strip() + elif line.find('password:',0)==0: + passwd=line[9:].strip() credentials=(phone,passwd) try: - stack = sendclient.YowsupSendStack(credentials, [([sys.argv[1], sys.argv[2]])],False) - stack.start() + stack = sendclient.YowsupSendStack(credentials, [([sys.argv[1], sys.argv[2]])],False) + stack.start() except KeyboardInterrupt: - print 'Message delivered, did it arrive?' - sys.exit(0) + print ('Message delivered, did it arrive?') + sys.exit(0) diff --git a/yow-daemon.py b/yow-daemon.py index ae40660..3ea422b 100755 --- a/yow-daemon.py +++ b/yow-daemon.py @@ -1,8 +1,8 @@ #!/usr/bin/env python import sys,time,os -from daemon import Daemon -from layer import DaemonLayer +from daemon import Daemon +from layer import DaemonLayer from yowsup.layers.auth import YowAuthenticationProtocolLayer from yowsup.layers.protocol_messages import YowMessagesProtocolLayer from yowsup.layers.protocol_receipts import YowReceiptProtocolLayer @@ -13,80 +13,82 @@ from yowsup.common import YowConstants from yowsup.layers import YowLayerEvent from yowsup.stacks import YowStack, YOWSUP_CORE_LAYERS -from yowsup import env +from yowsup import env import subprocess import logging logging.basicConfig(level=logging.ERROR) class YowsupDaemon(Daemon): - def run(self): - mess=None - to=None - with open(appPath+'/config.cfg') as f: - for line in f: - if line.find('phone number:',0)==0: - phone=line[13:] - phone=phone.strip() - elif line.find('password:',0)==0: - passw=line[9:].strip() - elif line.find('send_message_startup:',0)==0: - mess=line[21:-1] - mess= '\'' + mess + '\'' - elif line.find('allowed1:',0)==0: - to=line[9:-1] + def run(self): + mess=None + to=None + phone=None + passw=None + with open(appPath+'/config.cfg') as f: + for line in f: + if line.find('phone number:',0)==0: + phone=line[13:] + phone=phone.strip() + elif line.find('password:',0)==0: + passw=line[9:].strip() + elif line.find('send_message_startup:',0)==0: + mess=line[21:-1] + mess= '\'' + mess + '\'' + elif line.find('allowed1:',0)==0: + to=line[9:-1] CREDENTIALS = (phone, passw) - print '/send.py '+to+' '+mess - p=subprocess.Popen(appPath+'/send.py '+to+' '+mess,stdout=subprocess.PIPE, shell=True) - (output,err)=p.communicate() - while True: - layers = ( - DaemonLayer, - (YowAuthenticationProtocolLayer, YowMessagesProtocolLayer, YowReceiptProtocolLayer,YowAckProtocolLayer) - ) + YOWSUP_CORE_LAYERS - - stack = YowStack(layers) - stack.setProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS, CREDENTIALS) - stack.setProp(YowNetworkLayer.PROP_ENDPOINT, YowConstants.ENDPOINTS[0]) - stack.setProp(YowCoderLayer.PROP_DOMAIN, YowConstants.DOMAIN) - stack.setProp(YowCoderLayer.PROP_RESOURCE, env.CURRENT_ENV.getResource()) - stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT)) - interface=stack.getLayer(6) - interface.initialize(appPath) - try: - stack.loop() - except: - pass + print ('/send.py '+to+' '+mess) + p=subprocess.Popen(appPath+'/send.py '+to+' '+mess,stdout=subprocess.PIPE, shell=True) + (output,err)=p.communicate() + while True: + layers = ( + DaemonLayer, + (YowAuthenticationProtocolLayer, YowMessagesProtocolLayer, YowReceiptProtocolLayer,YowAckProtocolLayer) + ) + YOWSUP_CORE_LAYERS + + stack = YowStack(layers) + stack.setProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS, CREDENTIALS) + stack.setProp(YowNetworkLayer.PROP_ENDPOINT, YowConstants.ENDPOINTS[0]) + stack.setProp(YowCoderLayer.PROP_DOMAIN, YowConstants.DOMAIN) + stack.setProp(YowCoderLayer.PROP_RESOURCE, env.CURRENT_ENV.getResource()) + stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT)) + interface=stack.getLayer(6) + interface.initialize(appPath) + try: + stack.loop() + except: + pass if __name__== '__main__': - daemon = YowsupDaemon('/tmp/yowsup-daemon.pid',True) - appPath=os.getcwd() - usage='Use %s help\n' %sys.argv[0] - if len(sys.argv)==2: - if 'start' == sys.argv[1]: - daemon.start() - elif 'stop' == sys.argv[1]: - daemon.stop() - elif 'status' == sys.argv[1]: - daemon.status() - elif 'restart' == sys.argv[1]: - daemon.restart() - elif 'undaemon' == sys.argv[1]: - daemon.nodaemon() - elif 'help' == sys.argv[1]: - with open(appPath+'/Instructions') as f: - for line in f: - print line[0:-1] - elif 'about' == sys.argv[1]: - print 'Yow-daemon, yowsup based remote control,\n'\ - 'Tread Soft 2015 tweeter: @treadsoftblog' - elif 'license' ==sys.argv[1]: - with open(appPath+'/LICENSE') as f: - for line in f: - print line - else: - print usage - sys.exit(2) - sys.exit(0) - else: - print usage - sys.exit(2) + daemon = YowsupDaemon('/tmp/yowsup-daemon.pid',True) + appPath=os.getcwd() + usage='Use %s help\n' %sys.argv[0] + if len(sys.argv)==2: + if 'start' == sys.argv[1]: + daemon.start() + elif 'stop' == sys.argv[1]: + daemon.stop() + elif 'status' == sys.argv[1]: + daemon.status() + elif 'restart' == sys.argv[1]: + daemon.restart() + elif 'undaemon' == sys.argv[1]: + daemon.nodaemon() + elif 'help' == sys.argv[1]: + with open(appPath+'/Instructions') as f: + for line in f: + print (line[0:-1]) + elif 'about' == sys.argv[1]: + print ('Yow-daemon, yowsup based remote control,\n') + 'Tread Soft 2015 tweeter: @treadsoftblog' + elif 'license' ==sys.argv[1]: + with open(appPath+'/LICENSE') as f: + for line in f: + print (line) + else: + print (usage) + sys.exit(2) + sys.exit(0) + else: + print (usage) + sys.exit(2)