quassel-search.py

This is a quick, simple and easy script to search a Quassel database (SQLite only) for some text in your backlog.

#!/usr/bin/env python
 
"""
Quassel Search 0.1 for Quassel 0.4
----------------------------------
This is a quick, simple and easy script to search a Quassel database for some
text in your backlog.
 
Written by Raoul Snyman [raoul.snyman AT saturnlaboratories DOT co DOT za]
 
License:
--------
Copyright (c) 2009 Raoul Snyman. All rights reserved.
 
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
of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
"""
 
import os
import sys
import codecs
import sqlite3 as sqlite
from datetime import datetime
from exceptions import Exception
from optparse import OptionParser
 
def main():
    sys.stdout = codecs.getwriter('utf8')(sys.stdout)
    version = u'Quassel Search 0.1 for Quassel 0.4\nCopyright (c) 2009 Raoul Snyman\nThis program is licensed under the GNU General Public License'
    usage = u'%prog [options] <keywords>'
    parser = OptionParser(version=version, usage=usage)
    parser.add_option('-d', '--database', dest='database', metavar='FILE',
                  default='quassel-storage.sqlite',
                  help='Specify the database file to be used. If no file is specified, "quassel-storage.sqlite" in the current directory will be used.')
    parser.add_option('-u', '--username', dest='username', metavar='USER',
                  default=None, help='Specify a username. [REQUIRED]')
    parser.add_option('-n', '--network', dest='network', metavar='NETWORK',
                  default=None, help='Specify the network to search.')
    parser.add_option('-b', '--buffer', dest='buffer', metavar='BUFFER',
                  default=None, help='Specify the Quassel buffer to search (channels must be prefixed with #).')
    (options, args) = parser.parse_args()
    if options.username is None:
        parser.error(u'The username is required.\n')
    if options.buffer is not None and options.network is None:
        parser.error(u'You have to specify a network when searching by buffer.\n')
    user_id = 0
    network_id = 0
    buffer_ids = []
    connection = sqlite.connect(os.path.abspath(options.database))
    cursor = connection.cursor()
    try:
        cursor.execute(u'SELECT userid FROM quasseluser WHERE username LIKE ?',
            (options.username,))
    except Exception, e:
        print u'An error occurred: "%s"' % e.message
        return 1
    user = cursor.fetchone()
    if user is None:
        print u'There are no users with the username "%s". Please note that the username is case sensitive.' % options.username
        return 1
    else:
        user_id = user[0]
    if options.network is not None:
        try:
            cursor.execute(u'SELECT networkid FROM network WHERE LOWER(networkname) LIKE LOWER(?) AND userid = ?',
                (options.network, user_id))
        except Exception, e:
            print u'An error occurred: "%s"' % e.message
            return 1
        network = cursor.fetchone()
        if network is None:
            print u'There was no network with the name "%s"' % options.network
            return 1
        else:
            network_id = network[0]
        if options.buffer is not None:
            try:
                cursor.execute(u'SELECT bufferid FROM buffer WHERE buffercname LIKE LOWER(?) AND userid = ? AND networkid = ?',
                    (options.buffer, user_id, network_id))
            except Exception, e:
                print u'An error occurred: %s' % e.message
                return 1
            buffer = cursor.fetchone()
            if buffer is None:
                print u'There are no buffers with the name "%s"' % buffer
                return 1
            else:
                buffer_ids.append(buffer[0])
        else:
            try:
                cursor.execute(u'SELECT bufferid FROM buffer WHERE userid = ? AND networkid = ?',
                    (user_id, network_id))
            except Exception, e:
                print u'An error occurred: %s' % e.message
                return 1
            buffers = cursor.fetchall()
            if len(buffers) == 0:
                print u'There are no buffers for the network named "%s"' % options.network
                return 1
            else:
                for buffer in buffers:
                    buffer_ids.append(buffer[0])
    else:
        try:
            cursor.execute(u'SELECT bufferid FROM buffer WHERE userid = ?',
                (user_id,))
        except Exception, e:
            print u'An error occurred: %s' % e.message
            return 1
        buffers = cursor.fetchall()
        if len(buffers) == 0:
            print u'There are no buffers for the user "%s"' % options.username
            return 1
        for buffer in buffers:
            buffer_ids.append(buffer[0])
    search_sql = u'SELECT network.networkname, buffer.buffername, ' + \
        u'backlog.time, sender.sender, backlog.message FROM backlog ' + \
        u'JOIN sender ON backlog.senderid = sender.senderid ' + \
        u'JOIN buffer ON backlog.bufferid = buffer.bufferid ' + \
        u'JOIN network ON buffer.networkid = network.networkid ' + \
        u'WHERE backlog.message LIKE "%%%s%%"' % args[0]
    try:
        cursor.execute(search_sql)
    except Exception, e:
        print u'An error occurred: %s' % e.message
        return 1
    try:
        results = cursor.fetchall()
    except Exception, e:
        print search_sql
        print u'An error occurred: %s' % e.message
        return 1
    if len(results) == 0:
        print u'No results for your search query'
        return 0
    else:
        for row in results:
            network_name = row[0]
            channel_name = row[1]
            message_time = str(datetime.fromtimestamp(row[2]))
            sender_name = unicode(row[3]).rsplit(u'!')[0]
            message_text = row[4]
            print u'(%s.%s) %s <%s> %s' % (network_name, channel_name,
                message_time, sender_name, message_text)
 
if __name__ == u'__main__':
    main()