pidgin: disconnect specific accounts from cron

At the end of the day, I needed a way to automatically disconnect from my personal instant messaging accounts (jabber, aim), while staying connected to my work jabber server. This could be done manually ( Accounts -> Manage Accounts -> Uncheck $AccountName), however I tend to be extremely forgetful and often stay logged in.

With the aid of python, I wrote a script that will disconnect specific libpurple/pidgin accounts. Modify the accounts list in the script to reflect that accounts you want to disconnect.

This script was a bit tricky, because purple-remote uses dbus to communicate with pidgin/libpurple. Since cron sets up a bare minimum environment, we need to detect the active dbus session and set the following dbus environmental variables: DBUS_SESSION_BUS_ADDRESS, DBUS_SESSION_BUS_PID, DBUS_SESSION_BUS_WINDOWID. With these environment variable set, we identify the account id for each account you specified, and then tell libpurple to disable that account.

#!/usr/bin/python

import subprocess
import sys
import os
import re

accounts=[{'name':'pyther24', 'protocol':'prpl-aim' },
          {'name':'matthew@pyther.net/Work', 'protocol':'prpl-jabber'},
          {'name':'pyther24@gmail.com/Work', 'protocol':'prpl-jabber'}]

def check_pid(pid):
    """ Check For the existence of a unix pid. """
    try:
        os.kill(pid, 0)
    except OSError:
        return False
    else:
        return True

def main():
    if len(sys.argv) > 1 and sys.argv[1] == "login":
        ACCOUNT_ENABLE=1
    else:
        ACCOUNT_ENABLE=0

    # We need to get the dbus environment variable for purple-remote to work
    # These environment variables are stored in $HOME/.dbus/session-bus
    # there may be old sessions stored in .dbus/session-bus, we need to determine
    # which session to use

    env = os.environ.copy()
    # Fetch all sessions in $HOME/.dbus/session-bus
    dbus_dir=os.path.join(env['HOME'],'.dbus/session-bus')
    dbus_sessions=[]
    for filename in os.listdir(dbus_dir):
        filepath = os.path.join(dbus_dir,filename)
        session=dict()
        with open(filepath, 'r') as f:
            for line in f.readlines():
                if re.match('^#',line):
                    continue
                var,value=line.strip().split('=',1)
                session[var]=value
        dbus_sessions.append(session)

    # Determine which dbus session to use
    # Check pid to see if it is alive
    # If pid is alive see if the name contains dbus-daemon
    for s in dbus_sessions:
        pid=s['DBUS_SESSION_BUS_PID']

        if os.path.exists('/proc/{0}'.format(pid)):
            with open('/proc/{0}/cmdline'.format(pid)) as f:
                cmdline = f.readline().strip()
        else:
            # DBUS process must be dead
            continue

        if re.search('dbus-daemon',cmdline):
            env['DBUS_SESSION_BUS_ADDRESS'] = s['DBUS_SESSION_BUS_ADDRESS']
            env['DBUS_SESSION_BUS_PID'] = s['DBUS_SESSION_BUS_PID']
            env['DBUS_SESSION_BUS_WINDOWID'] = s['DBUS_SESSION_BUS_WINDOWID']
            break

    # Get account ids for each account define above
    # Disable / Enable each account

    for a in accounts:
        p = subprocess.Popen(['purple-remote',
          'PurpleAccountsFind({0},{1})'.format(a['name'],a['protocol'])],
          stdout=subprocess.PIPE,stderr=subprocess.PIPE,env=env)

        p.wait()

        # Store ID
        try:
            id = int(p.communicate()[0].strip())
        except ValueError:
            print('Could fetch id for account {0}'.format(a['name']))
            continue

        # Disable Account
        p = subprocess.call(['purple-remote',
          'PurpleAccountSetEnabled({0},{1},{2})'.format(int(id),'gtk-gaim',ACCOUNT_ENABLE)],env=env)
    return

if __name__ == '__main__':
    main()


Uploader

A few months ago, I was talking to a friend and he wanted to share some files with me. However, we had no easy of doing this. Pondering about the problem, I though it would be great if there was a uploader with some basic user authentication.  This brought about the birth of uploader. My biggest problem that I faced was the fact that I had no idea how to work with sessions and sqlite databases. That didn’t stop me though! During winter break and I went to tackle the challenge.

After digging through a lot of examples on the webpy.org website, I was eventually able to throw together something that worked. Winter break ended, the program was usable, and was left, without love, on my server.

Just last week, I started to play with uploader again and I noticed that the code was a disaster and confusing. So I started to rewrite the parts of the code that were bad and added comments. Since I already stumbled with sessions and database objects I had a much better understanding on how they worked and how to implement them into the code. During the last three days I have released uploader.

Github Page:  http://github.com/pyther/uploader
Project Page: http://pyther.net/projects/uploader/

Screenshots:

File UploadAdministrator Panel


New Avatar

Well thanks to ghost1227 I now have a new avatar. I was going for something along the lines of a python (snake), because I’ve had a lot of people ask me if my username has to do with python (the coding language). Initially when I first came up with the username I wasn’t even thinking about that!

So here it is, my new avatar:

Pythers Avatar

Don’t I look handsome?