summaryrefslogtreecommitdiffstats
path: root/abs/core/LinHES-system
diff options
context:
space:
mode:
authorJames Meyer <james.meyer@operamail.com>2012-09-27 05:04:37 (GMT)
committerJames Meyer <james.meyer@operamail.com>2012-09-27 05:04:37 (GMT)
commit2549b610a84a5e17aad9d8dbc8422f0719709436 (patch)
treeecdfddb106277272ed3180bfa87efcded7ffd5ed /abs/core/LinHES-system
parentc96cd6fab2342335a4f64b7eb2c843cd576eb610 (diff)
downloadlinhes_pkgbuild-2549b610a84a5e17aad9d8dbc8422f0719709436.zip
linhes_pkgbuild-2549b610a84a5e17aad9d8dbc8422f0719709436.tar.gz
linhes_pkgbuild-2549b610a84a5e17aad9d8dbc8422f0719709436.tar.bz2
LinHES-system: enhance msg_client.py and msg_deamon.py to support :
msg_client.py --clear --tag to clear the queue, with the --tag then the whole queue is cleared --msg --tag to add messages to que --kill kill whatever is currently being displayed
Diffstat (limited to 'abs/core/LinHES-system')
-rwxr-xr-xabs/core/LinHES-system/msg_client.py31
-rwxr-xr-xabs/core/LinHES-system/msg_daemon.py375
2 files changed, 364 insertions, 42 deletions
diff --git a/abs/core/LinHES-system/msg_client.py b/abs/core/LinHES-system/msg_client.py
index 3c53857..175933f 100755
--- a/abs/core/LinHES-system/msg_client.py
+++ b/abs/core/LinHES-system/msg_client.py
@@ -3,6 +3,8 @@
import socket
import sys
+import argparse
+import pickle
# Create a UDS socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
@@ -33,10 +35,25 @@ def send_message(message):
if __name__ == "__main__":
- if len(sys.argv) == 2:
- send_message(sys.argv[1])
- else:
- print "Unknown command"
- print "usage: %s msg to display" % sys.argv[0]
- sys.exit(2)
- sys.exit(0)
+ parser = argparse.ArgumentParser()
+
+ parser.add_argument('--tag', action='store', dest='tag',help='message tag')
+ parser.add_argument('--timeout', action='store', dest='timeout',help='time to display message')
+ action = parser.add_mutually_exclusive_group(required=True)
+ action.add_argument('--msg', action='store', dest='msg', help='Add message to the queue')
+ action.add_argument('--clear', action='store_true', help='Remove message from queue that match tag')
+ action.add_argument('--kill', action='store_true', help='Kill current msg thats displayed')
+
+ results = parser.parse_args()
+ resultsdict = vars(results)
+
+ if results.msg :
+ cmd = "msg"
+ elif results.clear:
+ cmd = "clear"
+ elif results.kill:
+ cmd = "kill"
+
+ arg_dict = {'cmd':cmd , 'msg':resultsdict['msg'] , 'tag':resultsdict['tag'] , 'timeout':resultsdict['timeout']}
+ send_message(pickle.dumps(arg_dict))
+ #sys.exit(0)
diff --git a/abs/core/LinHES-system/msg_daemon.py b/abs/core/LinHES-system/msg_daemon.py
index 5ca5b09..b766aae 100755
--- a/abs/core/LinHES-system/msg_daemon.py
+++ b/abs/core/LinHES-system/msg_daemon.py
@@ -4,43 +4,348 @@
import socket
import sys
import os
-from subprocess import call
+import pickle
+import operator
+import threading
+import time
+import aosd
+import ConfigParser
+import multiprocessing
+import subprocess,signal
+
+sys.path.append('/etc')
server_address = '/run/msg_socket'
+class msg_aosd():
+ def scroll(self,osd, width, height, display_time,position):
+ pos = position
+ step = 1
-# Make sure the socket does not already exist
-try:
- os.unlink(server_address)
-except OSError:
- if os.path.exists(server_address):
- raise
-# Create a UDS socket
-sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-# Bind the socket to the port
-print >>sys.stderr, 'starting up on %s' % server_address
-sock.bind(server_address)
-#change permissions of socket
-os.chmod(server_address,0777)
-
-# Listen for incoming connections
-sock.listen(1)
-
-while True:
- # Wait for a connection
- connection, client_address = sock.accept()
- try:
- #print >>sys.stderr, 'connection from', client_address
- msg=""
- # Receive the data in small chunks and retransmit it
- while True:
- data = connection.recv(16)
- msg+=data
- if data:
- continue
+ osd.set_position(pos, width, height)
+ (x, y, _, _) = osd.get_geometry()
+ osd.set_position_offset(width, height)
+ osd.show()
+
+ x -= 1
+ y += height - 1;
+ for i in range(1, height + 1, step):
+ osd.loop_for(5)
+ y -= step
+ osd.set_geometry(x, y, width, i)
+
+ osd.set_position(pos, width, height)
+ osd.set_position_offset(-1, -1)
+ (x, y, _, _) = osd.get_geometry()
+ #time to display
+ osd.loop_for(display_time)
+ for i in range(height, 0, -step):
+ y += step
+ osd.set_geometry(x, y, width, i);
+ osd.loop_for(1);
+
+ osd.hide();
+
+ def setup(self,font_color,font_type):
+ osd = aosd.AosdText()
+ osd.set_transparency(aosd.TRANSPARENCY_COMPOSITE)
+ if osd.get_transparency() != aosd.TRANSPARENCY_COMPOSITE:
+ osd.set_transparency(aosd.TRANSPARENCY_NONE)
+
+ osd.geom_x_offset = 10
+ osd.geom_y_offset = 0
+
+ osd.back_color = "white"
+ osd.back_opacity = 50
+
+ osd.shadow_color = "black"
+ osd.shadow_opacity = 127
+ osd.shadow_x_offset = 2
+ osd.shadow_y_offset = 2
+
+ osd.fore_color = font_color
+ osd.fore_opacity = 255
+
+ osd.set_font(font_type)
+ osd.wrap = aosd.PANGO_WRAP_WORD_CHAR
+ osd.alignment = aosd.PANGO_ALIGN_LEFT
+ osd.set_layout_width(osd.get_screen_wrap_width())
+ return osd
+
+ def set_string(self, osd, text):
+ osd.set_text(text)
+ return osd.get_text_size()
+
+ def setup_config(self):
+ module_config = ConfigParser.RawConfigParser()
+ try:
+ module_config.read('/usr/MythVantage/etc/msg.cfg')
+ except:
+ pass
+ return module_config
+
+
+
+ def display (self,flags,display_time=-1):
+ """
+ parse the msg for display.
+ """
+ try:
+ text,config_section=flags.split("|")
+ if config_section == '':
+ config_section="default"
+ except:
+ text=flags
+ config_section="default"
+
+ module_config = self.setup_config()
+
+ position=6
+ font_color="green"
+ font_type="Times New Roman Italic 36"
+
+ if display_time <= 0 :
+ try:
+ display_time = int(module_config.get(config_section,"display_time"))
+ except:
+ display_time = 5000
+ pass
+ try:
+ position = int(module_config.get(config_section,"position"))
+ except:
+ pass
+ try:
+ font_color = module_config.get(config_section,"font_color")
+ except:
+ pass
+ try:
+ font_type = module_config.get(config_section,"font_type")
+ except:
+ pass
+
+ #this bit of code converts a \n to EOL/BREAK
+ textline=text.split('\\n')
+ try:
+ textline.remove(' ')
+ except:
+ pass
+ text=chr(10).join(textline)
+
+ #cmd = sub_process.Popen("/usr/bin/wall %s" % text,stdout=sub_process.PIPE,shell=True)
+ #data = cmd.communicate()[0]
+ osd = self.setup(font_color, font_type)
+ width, height = self.set_string(osd, text)
+ self.scroll(osd, width, height, display_time, position)
+
+ return ("Message delivered")
+
+
+class msg_xosd():
+ """Crude wrapper for xosd_cat"""
+ def __init__ (self):
+ pass
+
+ def set_default_values(self):
+ self.color="yellow"
+ self.outline="2"
+ self.outlinecolour="black"
+ self.shadow="0"
+ self.shadowcolour="black"
+ self.font="-adobe-helvetica-bold-*-*-*-34-*-*-*-*-*-*-*"
+ return
+
+ def set_parameters(self):
+ xosd_cfg={}
+ file_name = "/etc/osd_cat.cfg"
+ try:
+ config_file = open(file_name)
+ except:
+ set_default_values()
+ return
+
+ for line in config_file:
+ line = line.strip()
+ if line and line[0] is not "#" and line[-1] is not "=":
+ var, val = line.rsplit("=", 1)
+ val = val.split("#")[0]
+ val = val.strip('"')
+ xosd_cfg[var.strip()] = val.strip()
+ self.color = xosd_cfg['color']
+ self.outline = xosd_cfg['outline']
+ self.outlinecolour = xosd_cfg['outlinecolour']
+ self.shadow = xosd_cfg['shadow']
+ self.shadowcolour = xosd_cfg['shadowcolour']
+ self.font = xosd_cfg['font']
+
+ def display(self,msg,display_time):
+ self.set_parameters()
+ cmd = "echo -e \"%s\" | DISPLAY=127.0.0.1:0 osd_cat --pos=middle --align=center --offset=200 --delay=%s --color=%s --outline=%s --outlinecolour=%s --shadow=%s --shadowcolour=%s --font=\"%s\"" %(msg,display_time,self.color,self.outline,self.outlinecolour,self.shadow,self.shadowcolour,self.font)
+ #set a process group on the OS, so that the kill gets them all. No one survives or becomes a zombie
+ self.p = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,preexec_fn=os.setsid)
+ self.processID = self.p.pid
+ stdout,stderr = self.p.communicate()
+
+ def kill(self):
+ try:
+ os.killpg(self.processID,signal.SIGTERM)
+ except:
+ pass
+
+class Msg_Queue():
+ def __init__(self):
+ self.msglist=[]
+ self.msg_slot = 0
+
+ def get_msg(self):
+ return self.msglist.pop(0)
+ pass
+
+ def add_msg(self,cmddict):
+ #print "Adding msg to msg queue"
+ self.inc_last_msg_slot()
+ cmddict['slot'] = self.msg_slot
+ self.msglist.append(cmddict)
+
+
+ def clear_msg(self,msg_tag):
+ #print "Clearing out list of %s" %msg_tag
+ #loop over list in reverse
+ for i in xrange(len(self.msglist) - 1, -1, -1):
+ #access list by index, look at the key tag
+ if self.msglist[i]['tag'] == msg_tag:
+ del self.msglist[i]
+
+ def clear(self):
+ #print "Clearing out entire queue"
+ del self.msglist[:]
+
+ def sort(self,keyvalue):
+ self.msglist.sort(key=operator.itemgetter(keyvalue))
+
+ def search(self,key,value):
+ pass
+
+ def print_queue(self):
+ print "############################"
+ for i in self.msglist:
+ for key, value in i.iteritems():
+ print key,":", value
+ print "-----"
+
+ def get_last_msg_slot(self):
+ return self.msg_slot
+
+ def inc_last_msg_slot(self):
+ self.msg_slot = self.msg_slot + 1
+
+
+class msg_queue_runner(threading.Thread):
+ """Threaded Queue runner for testing things"""
+ def __init__(self, msg_queue):
+ threading.Thread.__init__(self)
+ self.msg_queue = msg_queue
+ self.out_msg = msg_aosd()
+ self.out_xosd = msg_xosd()
+
+ def get_current_style(self):
+ style = "default"
+ if os.path.exists('/etc/X11/WINDOWMANAGER'):
+ command = ['bash', '-c', 'source /etc/X11/WINDOWMANAGER && echo $STARTUP_STYLE']
+ proc = subprocess.Popen(command, stdout = subprocess.PIPE)
+
+ for line in proc.stdout:
+ if line.strip() == "":
+ style = "default"
else:
- call(["/usr/LH/bin/lh_message.sh", msg])
- break
+ style = line.strip()
+ break
+ proc.communicate()
+ else:
+ style = "default"
+ return style
+
+
+ def kill_current(self):
+ style = self.get_current_style()
+ #print "Killing current display"
+ if style == "enhanced":
+ self.p.terminate()
+ elif style == "default":
+ #self.p.terminate()
+ self.out_xosd.kill()
+
+ def run(self):
+ while True:
+ try:
+ msgdict = self.msg_queue.get_msg()
+ style = self.get_current_style()
+ if msgdict['timeout'] == None:
+ display_time = 3
+
+ # display message here
+ msgtext = msgdict['msg']
+ if style == "enhanced":
+ display_time = display_time * 1000
+ self.p = multiprocessing.Process(target=self.out_msg.display, args=(msgtext,display_time))
+ self.p.start()
+ self.p.join()
+ elif style == "default":
+ display_time = int(msgdict['timeout'])
+ self.out_xosd.display(msgtext,display_time)
+
+ except:
+ time.sleep(1)
+ continue
+
+
+msg_queue = Msg_Queue()
+
+
+if __name__ == "__main__":
+ # Make sure the socket does not already exist
+ try:
+ os.unlink(server_address)
+ except OSError:
+ if os.path.exists(server_address):
+ raise
+ # Create a UDS socket
+ sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ # Bind the socket to the port
+ print >>sys.stderr, 'starting up on %s' % server_address
+ sock.bind(server_address)
+ #change permissions of socket
+ os.chmod(server_address,0777)
+
+ # Listen for incoming connections
+ sock.listen(1)
+ #start msg display thread
+ msgthread = msg_queue_runner(msg_queue)
+ msgthread.setDaemon(True)
+ msgthread.start()
+
+
+ #main loop that reads in the cmddict, never exits
+ while True:
+ # Wait for a connection
+ connection, client_address = sock.accept()
+ try:
+ sf = connection.makefile("r+b", bufsize=0)
+ data = sf.read()
+ cmddict = (pickle.loads(data))
+
+ if cmddict['cmd'] == "msg":
+ #add to msg_queue
+ msg_queue.add_msg(cmddict)
+ elif cmddict['cmd'] == 'clear':
+ if cmddict['tag'] == '' or cmddict['tag'] == None :
+ msg_queue.clear()
+ else:
+ msg_queue.clear_msg(cmddict['tag'])
+ elif cmddict['cmd'] == 'kill':
+ msgthread.kill_current()
+ ## call(["/usr/LH/bin/lh_message.sh", msg])
+ #break
+ finally:
+ # Clean up the connection
+ connection.close()
+
- finally:
- # Clean up the connection
- connection.close()