G15 Pidgin Script

Description

I call a Logitech G15 my own and I want to have a little plugin to see all incoming messages from my buddies. Piding offers a nice interface with DBus and writing a Python script isn't that though so here is my solution.

Preparations

You need to have G15Daemon and the G15Tools with g15composer installed. Using Debian (lenny/testing) this shouldn't be a hindrance.

Install the following packages:

aptitude install g15daemon g15composer pyhton-dbus

DBus should be installed already. When you have basic Debian installation.

Sample Image

Code

Download g15pidgin.py

g15pidgin.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
"""
Copyright (C) 2008 Julian Knauer <jpk@goatpr0n.de>
"
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, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
"
Maintainer:         Julian Knauer <jpk@goatpr0n.de>
URL:		    http://wiki.goatpr0n.de/code/python/g15pidgin
Version:	    2008-04-16
"""
 
import os, sys
import dbus, gobject, Queue
from dbus.mainloop.glib import DBusGMainLoop
 
 
# --- Setup starts here ---
use_encoding = 'latin-1' # for Umlauts
use_fifopath = os.environ.get('HOME')+'/.g15fifo-'+os.environ.get('LOGNAME')
# --- Setup ends here -----
 
 
def strip_ml_tags(in_text):
    """Description: Removes all HTML/XML-like tags from the input text.
    Inputs: s --> string of text
    Outputs: text string without the tags
 
    # doctest unit testing framework
 
    >>> test_text = "Keep this Text <remove><me /> KEEP </remove> 123"
    >>> strip_ml_tags(test_text)
    'Keep this Text  KEEP  123'
    """
    # convert in_text to a mutable object (e.g. list)
    s_list = list(in_text)
    i,j = 0,0
 
    while i < len(s_list):
        # iterate until a left-angle bracket is found
        if s_list[i] == '<':
            while s_list[i] != '>':
                # pop everything from the the left-angle bracket until the right-angle bracket
                s_list.pop(i)
                # pops the right-angle bracket, too
            s_list.pop(i)
        elif s_list[i] == '&': # suggested by Ronny Bremer through comment on goatpr0n.de
            while s_list[i] != ';':
                s_list.pop(i)
            s_list.pop(i)
        else:
            i += 1
 
    # convert the list back into text
    join_char=''
    return join_char.join(s_list)
 
 
def dispatch_message_cb(account, sender, message, conversation, flags):
    global messages, purple
 
    buddy = purple.PurpleFindBuddy(account, sender)
    alias = purple.PurpleBuddyGetAlias(buddy)
    name = purple.PurpleBuddyGetName(buddy)
    text = strip_ml_tags(message).replace('"', '\'\'')
    msg = '"%s (%s)" "> %s"' % (alias, name, text)
    messages.append(msg)
    if len(messages) > 3:
        messages.popleft()
 
    buffer = ''
    for i in range(len(messages)):
        buffer = buffer + messages[i]
        display_message(buffer)
 
 
def display_message(data):
    global use_encoding, use_fifopath
 
    try:
        fifo = os.open(use_fifopath, os.O_WRONLY)
        if fifo:
            msg = 'TS ' + data + '\n'
            os.write(fifo, msg.encode(use_encoding))
            os.close(fifo)
    except IOError, err:
        print >>sys.stderr, 'Failed opening FIFO.'
 
 
if __name__ == '__main__':
    print 'Launching G15 IM Message Delivery-Service...'
 
    messages = Queue.deque()
 
    dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
    bus = dbus.SessionBus()
    obj = bus.get_object("im.pidgin.purple.PurpleService", "/im/pidgin/purple/PurpleObject")
    purple = dbus.Interface(obj, "im.pidgin.purple.PurpleInterface")
    bus.add_signal_receiver(dispatch_message_cb,
            dbus_interface='im.pidgin.purple.PurpleInterface',
            signal_name='ReceivedImMsg')
 
    loop = gobject.MainLoop()
    loop.run()
 
# vim:ts=4:sw=4:et:enc=utf-8:

Usage

You need to have g15deamon and g15composer running.

Start the G15 Daemon:

invoke-rc.d g15daemon start

Run g15composer:

g15composer ~/.g15fifo-$(LOGNAME)

Now you have to wait that someone sends you a message.

Start the g15pidgin script:

# if script has executable bit set (chmod +x g15pidgin.py)
./g15pidgin.py &

# if not set as executable
python g15pidgin.py &

It could happen if you close the terminal where you have started the script, that the script terminates. To prevent this simply run one of the above commands to start the script, but put nohup before the command to ignore the signal.

nohup ./g15pidgin.py &

Known Bugs

  1. Fixed: When receiving a Unicode or malformed message, the message queue gets messed up a bit. after four valid messages it should get back to normal
  2. Catch SIGHUP

Discussion

Janelle, 2008/06/16 02:28

Okay, I've downloaded your script but the only scripts that are in pidgins folders are .so, not .py. I'm not sure where to go from here.

Julian Knauer, 2008/06/16 11:14

It's not a plugin for the g15daemon, it uses the g15composer to deliver the messages.

You simply start the composer and after, that you simply start this python script. You are right, I should have put this into the usage section

Please look at the Usage please, I'll update it ASAP (now)!

Ronny Bremer, 2008/09/17 15:17

Julian,

thanks for the script. I like it … it saves me from switching windows all the time :)

Quick suggestion. By replacing the code below it will also strip out HTML encoded characters, like ampersand and such.


  while i < len(s_list):
      # iterate until a left-angle bracket is found
      if s_list[i] == '<':
          while s_list[i] != '>':
              # pop everything from the the left-angle bracket until the right-angle bracket
              s_list.pop(i)
              # pops the right-angle bracket, too
          s_list.pop(i)
      else:
          # iterate until an ampersand is found
          if s_list[i] == '&':
              while s_list[i] != ';':
                  # pop everything from the the ampersand until the semicolon bracket
                  s_list.pop(i)
                  # pops the semicolon, too
              s_list.pop(i)
          else:
              i=i+1

—————–

There might even be a Python library for filtering HTML messages and all associated tags, but I am not good at Python unfortunately.

I couldn't figure out one thing. How to add a line break for longer messages? It will always cut them off on the LCD.

Yours,

Ronny

Julian Knauer, 2008/09/18 11:50

Thanks for your addition. I'll try to find out if there's already a function (There should be one).

Julian Knauer, 2009/02/20 14:09

Added to source

Julian O., 2011/11/02 13:20

what about the line breaks?

Akkeresu, 2009/10/12 23:38

Hey, is there any way to use this in Windows?

Julian Knauer, 2009/10/13 00:08

Hi, I'm sorry, but I don't think so. The tool g15composer and the socket file (the ~/.g15fifo-$(LOGNAME) file), which is used by the program, is only available for Linux, especially the socket.

Enter your comment. Wiki syntax is allowed:
If you can't read the letters on the image, download this .wav file to get them read to you.
 
code/python/g15pidgin.txt · Last modified: 2008/06/16 11:22 by jpk
CC Attribution-Noncommercial-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0