mcevent.py
changeset 11 5ee5101decd0
parent 10 cf31fa2e0bbc
child 12 5f16a0f3124c
equal deleted inserted replaced
10:cf31fa2e0bbc 11:5ee5101decd0
     3 #
     3 #
     4 #  Copyright (C) 2007 Adam Wolk "Mulander" <netprobe@gmail.com>
     4 #  Copyright (C) 2007 Adam Wolk "Mulander" <netprobe@gmail.com>
     5 #  Copyright (C) 2007, 2008 Mikael Berthe "McKael" <mikael@lilotux.net>
     5 #  Copyright (C) 2007, 2008 Mikael Berthe "McKael" <mikael@lilotux.net>
     6 #
     6 #
     7 # This script is provided under the terms of the GNU General Public License,
     7 # This script is provided under the terms of the GNU General Public License,
     8 # see the file COPYING in the root mcabber source directory.
     8 # see the file COPYING in this directory.
     9 #
     9 #
       
    10 """
       
    11 This script reads mcabber event lines from the standard input
       
    12 and creates events accordingly.  Examples:
       
    13 STATUS O user2@domain.org
       
    14 MSG IN user@domain.org
       
    15 UNREAD 1
       
    16 """
    10 
    17 
    11 import sys, getopt
    18 import sys, getopt
    12 import os
    19 import os
    13 import pynotify
    20 import pynotify
    14 
    21 
    15 CONFFILE = "mcevent.cfg"
    22 CONFFILE = "mcevent.cfg"
    16 
    23 
    17 # Default option values
    24 # Default option values
    18 opt = {
    25 OPT = {
    19         'use_notify': 0,
    26         'use_notify': 0,
    20         'use_voice':  0,
    27         'use_voice':  0,
    21         'use_sound':  1,
    28         'use_sound':  1,
    22         'short_nick': 1,
    29         'short_nick': 1,
    23         'unread_file': '',
    30         'unread_file': '',
    24         'snd_cmd_msg_in': '/usr/bin/play -V0 -v3 sound.wav',
    31         'snd_cmd_msg_in': '/usr/bin/play -V0 -v3 sound.wav',
    25 }
    32 }
    26 
    33 
    27 NOTIFY_TIMEOUT = 4000
    34 NOTIFY_TIMEOUT = 4000
    28 
    35 
    29 contact_map = { }
    36 CONTACT_MAP = { }
    30 # Nickname used for the notification
    37 # Nickname used for the notification
    31 
    38 
    32 contact_custom_msg = { }
    39 CONTACT_CUSTOM_MSG = { }
    33 # Message used for the notification
    40 # Message used for the notification
    34 
    41 
    35 online_alerts = { }
    42 ONLINE_ALERTS = { }
    36 # 0: disabled  1: normal notification  2: permanent notify box
    43 # 0: disabled  1: normal notification  2: permanent notify box
    37 
    44 
    38 voicemap = { }
    45 VOICEMAP = { }
    39 # Specify the name pronounced by espeak
    46 # Specify the name pronounced by espeak
    40 
    47 
    41 blacklist = { }
    48 BLACKLIST = { }
    42 # No notification for these JIDs
    49 # No notification for these JIDs
    43 
    50 
    44 CMD_ESPEAK = "/usr/bin/espeak"
    51 CMD_ESPEAK = "/usr/bin/espeak"
    45 
    52 
    46 ENCODING = ''
    53 ENCODING = ''
    47 
    54 
    48 def init_notify():
    55 def init_notify():
       
    56     """
       
    57     Initialize the pynotify subsystem.
       
    58     """
    49     import locale
    59     import locale
    50     global ENCODING, NOTIFY_LOADED
    60     global ENCODING, NOTIFY_LOADED
    51     pynotify.init('mcnotify')
    61     pynotify.init('mcnotify')
    52     ENCODING = (locale.getdefaultlocale())[1]
    62     ENCODING = (locale.getdefaultlocale())[1]
    53     NOTIFY_LOADED = True
    63     NOTIFY_LOADED = True
    54 
    64 
    55 def read_conf_from_file():
    65 def read_conf_from_file():
       
    66     """
       
    67     Read the configuration file.
       
    68     """
    56     import ConfigParser
    69     import ConfigParser
    57 
    70 
    58     config = ConfigParser.ConfigParser()
    71     config = ConfigParser.ConfigParser()
    59     config.read(CONFFILE)
    72     config.read(CONFFILE)
    60 
    73 
    61     contact_map.clear()
    74     CONTACT_MAP.clear()
    62     contact_custom_msg.clear()
    75     CONTACT_CUSTOM_MSG.clear()
    63     online_alerts.clear()
    76     ONLINE_ALERTS.clear()
    64     voicemap.clear()
    77     VOICEMAP.clear()
    65     blacklist.clear()
    78     BLACKLIST.clear()
    66 
    79 
    67     if config.has_option("Notifications", "notify"):
    80     if config.has_option("Notifications", "notify"):
    68         opt['use_notify'] = int(config.get("Notifications", "notify"))
    81         OPT['use_notify'] = int(config.get("Notifications", "notify"))
    69     if config.has_option("Notifications", "voice"):
    82     if config.has_option("Notifications", "voice"):
    70         opt['use_voice']  = int(config.get("Notifications", "voice"))
    83         OPT['use_voice']  = int(config.get("Notifications", "voice"))
    71     if config.has_option("Notifications", "sound"):
    84     if config.has_option("Notifications", "sound"):
    72         opt['use_sound']  = int(config.get("Notifications", "sound"))
    85         OPT['use_sound']  = int(config.get("Notifications", "sound"))
    73     if config.has_option("Notifications", "short_nick"):
    86     if config.has_option("Notifications", "short_nick"):
    74         opt['short_nick'] = int(config.get("Notifications", "short_nick"))
    87         OPT['short_nick'] = int(config.get("Notifications", "short_nick"))
    75     if config.has_option("Notifications", "unread_file"):
    88     if config.has_option("Notifications", "unread_file"):
    76         opt['unread_file'] = config.get("Notifications", "unread_file")
    89         OPT['unread_file'] = config.get("Notifications", "unread_file")
    77     if config.has_option("Notifications", "snd_cmd_msg_in"):
    90     if config.has_option("Notifications", "snd_cmd_msg_in"):
    78         opt['snd_cmd_msg_in'] = config.get("Notifications", "snd_cmd_msg_in")
    91         OPT['snd_cmd_msg_in'] = config.get("Notifications", "snd_cmd_msg_in")
    79 
    92 
    80     if config.has_section("Contacts"):
    93     if config.has_section("Contacts"):
    81         for cid in config.options("Contacts"):
    94         for cid in config.options("Contacts"):
    82             contact_map[cid] = config.get("Contacts", cid)
    95             CONTACT_MAP[cid] = config.get("Contacts", cid)
    83 
    96 
    84     if config.has_section("Contact_Customized_Messages"):
    97     if config.has_section("Contact_Customized_Messages"):
    85         for cid in config.options("Contact_Customized_Messages"):
    98         for cid in config.options("Contact_Customized_Messages"):
    86             contact_custom_msg[cid] = config.get("Contact_Customized_Messages",
    99             CONTACT_CUSTOM_MSG[cid] = config.get("Contact_Customized_Messages",
    87                                                  cid)
   100                                                  cid)
    88 
   101 
    89     if config.has_section("Alerts"):
   102     if config.has_section("Alerts"):
    90         for cid in config.options("Alerts"):
   103         for cid in config.options("Alerts"):
    91             online_alerts[cid] = int(config.get("Alerts", cid))
   104             ONLINE_ALERTS[cid] = int(config.get("Alerts", cid))
    92 
   105 
    93     if config.has_section("Voicemap"):
   106     if config.has_section("Voicemap"):
    94         for cid in config.options("Voicemap"):
   107         for cid in config.options("Voicemap"):
    95             voicemap[cid] = config.get("Voicemap", cid)
   108             VOICEMAP[cid] = config.get("Voicemap", cid)
    96 
   109 
    97     if config.has_section("Blacklist"):
   110     if config.has_section("Blacklist"):
    98         for cid in config.options("Blacklist"):
   111         for cid in config.options("Blacklist"):
    99             blacklist[cid] = int(config.get("Blacklist", cid))
   112             BLACKLIST[cid] = int(config.get("Blacklist", cid))
   100 
   113 
   101     if opt['use_notify'] and not NOTIFY_LOADED:
   114     if OPT['use_notify'] and not NOTIFY_LOADED:
   102         init_notify()
   115         init_notify()
   103 
   116 
   104 def say(buddy, text):
   117 def say(buddy, text):
       
   118     """
       
   119     Create a subprocess and run a speech synthesizer.
       
   120     """
   105     import subprocess
   121     import subprocess
   106     p = subprocess.Popen(CMD_ESPEAK, stdin=subprocess.PIPE, close_fds=True)
   122     p = subprocess.Popen(CMD_ESPEAK, stdin=subprocess.PIPE, close_fds=True)
   107     child_stdin = p.stdin
   123     child_stdin = p.stdin
   108     child_stdin.write(buddy + " " + text)
   124     child_stdin.write(buddy + " " + text)
   109     child_stdin.close()
   125     child_stdin.close()
   110 
   126 
   111 def notify(buddy, msg, timeout):
   127 def notify(buddy, msg, timeout):
       
   128     """
       
   129     Create a pynotify popup.
       
   130     """
   112     msgbox = pynotify.Notification(unicode(buddy, ENCODING),
   131     msgbox = pynotify.Notification(unicode(buddy, ENCODING),
   113                                    unicode(msg, ENCODING))
   132                                    unicode(msg, ENCODING))
   114     msgbox.set_timeout(timeout)
   133     msgbox.set_timeout(timeout)
   115     msgbox.set_urgency(pynotify.URGENCY_LOW)
   134     msgbox.set_urgency(pynotify.URGENCY_LOW)
   116     msgbox.show()
   135     msgbox.show()
   117 
   136 
   118 def get_nick(jid):
   137 def get_nick(jid):
   119     if jid in contact_map:
   138     """
   120         buddy = contact_map[jid]
   139     Return the nick of the given contact (JID).
       
   140     """
       
   141     if jid in CONTACT_MAP:
       
   142         buddy = CONTACT_MAP[jid]
   121     else:
   143     else:
   122         buddy = jid
   144         buddy = jid
   123 
   145 
   124     if opt['short_nick'] and '@' in buddy:
   146     if OPT['short_nick'] and '@' in buddy:
   125         buddy = buddy[0:buddy.index('@')]
   147         buddy = buddy[0:buddy.index('@')]
   126     return buddy
   148     return buddy
   127 
   149 
   128 def is_blacklisted(jid):
   150 def is_blacklisted(jid):
   129     if jid in blacklist and blacklist[jid]:
   151     """
       
   152     Return True if the given contcat (JID) is blacklisted.
       
   153     """
       
   154     if jid in BLACKLIST and BLACKLIST[jid]:
   130         return True
   155         return True
   131     return False
   156     return False
   132 
   157 
   133 def process_line(args):
   158 def process_line(args):
       
   159     """
       
   160     Parse the provided line and run events.
       
   161     """
   134     argn = len(args)
   162     argn = len(args)
   135 
   163 
   136     if argn < 2:
   164     if argn < 2:
   137         print "Ignoring invalid event line."
   165         print "Ignoring invalid event line."
   138         return
   166         return
   153         if not jid:
   181         if not jid:
   154             print "Ignoring invalid MSG event line."
   182             print "Ignoring invalid MSG event line."
   155             return
   183             return
   156 
   184 
   157         buddy = get_nick(jid)
   185         buddy = get_nick(jid)
   158         if jid in contact_custom_msg:
   186         if jid in CONTACT_CUSTOM_MSG:
   159             msg = contact_custom_msg[jid]
   187             msg = CONTACT_CUSTOM_MSG[jid]
   160         elif 'default' in contact_custom_msg:
   188         elif 'default' in CONTACT_CUSTOM_MSG:
   161             msg = contact_custom_msg['default']
   189             msg = CONTACT_CUSTOM_MSG['default']
   162         else:
   190         else:
   163             msg = 'sent you a message.'
   191             msg = 'sent you a message.'
   164 
   192 
   165         if not is_blacklisted(jid):
   193         if not is_blacklisted(jid):
   166             textmsg = None
   194             textmsg = None
   167 
   195 
   168             if filename and os.path.exists(filename):
   196             if filename and os.path.exists(filename):
   169                 f   = file(filename)
   197                 fileh = file(filename)
   170                 textmsg = f.read()
   198                 textmsg = fileh.read()
   171 
   199 
   172             if opt['use_notify']:
   200             if OPT['use_notify']:
   173                 if not textmsg:
   201                 if not textmsg:
   174                     textmsg = msg
   202                     textmsg = msg
   175                 notify(buddy, textmsg, NOTIFY_TIMEOUT)
   203                 notify(buddy, textmsg, NOTIFY_TIMEOUT)
   176 
   204 
   177             if opt['use_sound']:
   205             if OPT['use_sound']:
   178                 os.system(opt['snd_cmd_msg_in'] + '> /dev/null 2>&1')
   206                 os.system(OPT['snd_cmd_msg_in'] + '> /dev/null 2>&1')
   179 
   207 
   180             if opt['use_voice'] and not is_blacklisted(jid):
   208             if OPT['use_voice'] and not is_blacklisted(jid):
   181                 if jid in voicemap:
   209                 if jid in VOICEMAP:
   182                     buddy = voicemap[jid]
   210                     buddy = VOICEMAP[jid]
   183                 say(buddy, msg)
   211                 say(buddy, msg)
   184 
   212 
   185         if filename and os.path.exists(filename):
   213         if filename and os.path.exists(filename):
   186             os.remove(filename)
   214             os.remove(filename)
   187 
   215 
   188     elif event == 'STATUS':
   216     elif event == 'STATUS':
   189         jid = arg2
   217         jid = arg2
   190         if arg1 == 'O' and jid in online_alerts:
   218         if arg1 == 'O' and jid in ONLINE_ALERTS:
   191             alert_type = online_alerts[jid]
   219             alert_type = ONLINE_ALERTS[jid]
   192             if alert_type > 0:
   220             if alert_type > 0:
   193                 if opt['use_sound']:
   221                 if OPT['use_sound']:
   194                     os.system(opt['snd_cmd_msg_in'] + '> /dev/null 2>&1')
   222                     os.system(OPT['snd_cmd_msg_in'] + '> /dev/null 2>&1')
   195 
   223 
   196                 buddy = get_nick(jid)
   224                 buddy = get_nick(jid)
   197 
   225 
   198                 if opt['use_notify']:
   226                 if OPT['use_notify']:
   199                     if alert_type == 1:
   227                     if alert_type == 1:
   200                         timeout = NOTIFY_TIMEOUT
   228                         timeout = NOTIFY_TIMEOUT
   201                     else:
   229                     else:
   202                         timeout = pynotify.EXPIRES_NEVER
   230                         timeout = pynotify.EXPIRES_NEVER
   203                     notify(buddy, "is online", timeout)
   231                     notify(buddy, "is online", timeout)
   204 
   232 
   205                     if filename and os.path.exists(filename):
   233                     if filename and os.path.exists(filename):
   206                         os.remove(filename)
   234                         os.remove(filename)
   207 
   235 
   208                 if opt['use_voice']:
   236                 if OPT['use_voice']:
   209                     if jid in voicemap:
   237                     if jid in VOICEMAP:
   210                         buddy = voicemap[jid]
   238                         buddy = VOICEMAP[jid]
   211                     say(buddy, "is online now.")
   239                     say(buddy, "is online now.")
   212 
   240 
   213     elif event == 'UNREAD':
   241     elif event == 'UNREAD':
   214         # arg1 is the number of unread buffers
   242         # arg1 is the number of unread buffers
   215         if opt['unread_file'] != '':
   243         if OPT['unread_file'] != '':
   216             fileHandle = open(opt['unread_file'], 'w')
   244             fileh = open(OPT['unread_file'], 'w')
   217             fileHandle.write(arg1)
   245             fileh.write(arg1)
   218             fileHandle.close()
   246             fileh.close()
   219 
   247 
   220 
   248 
   221 ##### MAIN #####
   249 ##### MAIN #####
   222 
   250 
   223 try:
   251 try: