Logo Search packages:      
Sourcecode: weechat-scripts version File versions

urlgrab.py

#
# UrlGrab, version 1.0, for weechat version 0.1.6
#
#   Listens to all channels for URLs, collects them in a list, and launches
#   them in your favourite web server on the local host or a remote server.
#
# Usage:
#
#   The /url command provides access to all UrlGrab functions.  Run
#   '/url help' for complete command usage.
#
#   In general, use '/url list' to list the entire url list for the current
#   channel, and '/url <n>' to launch the nth url in the list.  For
#   example, to launch the first (and most-recently added) url in the list,
#   you would run '/url 1'
#
#   From the server window, you must specify a specific channel for the
#   list and launch commands, for example:
#     /url list #weechat 
#     /url 3 #weechat
#
# Configuration:
#
#   The '/url set' command lets you get and set the following options:
#
#   historysize
#     The maximum number of URLs saved per channel.  Default is 10
#
#   method
#     Must be one of 'local' or 'remote' - Defines how URLs are launched by
#     the script.  If 'local', the script will run 'localcmd' on the host.
#     If 'remote', the script will run 'remotessh remotehost remotecmd' on
#     the local host which should normally use ssh to connect to another
#     host and run the browser command there.
#
#   localcmd
#     The command to run on the local host to launch URLs in 'local' mode.
#     The string '%s' will be replaced with the URL.  The default is
#     'firefox %s'.
#
#   remotessh
#     The command (and arguments) used to connect to the remote host for
#     'remote' mode.  The default is 'ssh -x' which will connect as the
#     current username via ssh and disable X11 forwarding.
#
#   remotehost
#     The remote host to which we will connect in 'remote' mode.  For ssh,
#     this can just be a hostname or 'user@host' to specify a username
#     other than your current login name.  The default is 'localhost'.
#
#   remotecmd
#     The command to execute on the remote host for 'remote' mode.  The
#     default is 'bash -c "DISPLAY=:0.0 firefox %s"'  Which runs bash, sets
#     up the environment to display on the remote host's main X display,
#     and runs firefox.  As with 'localcmd', the string '%s' will be
#     replaced with the URL.
#
#   cmdoutput
#     The file where the command output (if any) is saved.  Overwritten
#     each time you launch a new URL.  Default is ~/.weechat/urllaunch.log
#
# Requirements:
#
#  - Designed to run with weechat version 1.0.6 or better.
#      http://weechat.flashtux.org/
#
# Acknowlegements:
#
#  - Based on an earlier version called 'urlcollector.py' by 'kolter' of
#    irc.freenode.net/#weechat Honestly, I just cleaned up the code a bit and
#    made the settings a little more useful (to me).
#
# Copyright (C) 2005 Jim Ramsay <i.am@jimramsay.com>
#
# 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 weechat

UC_NAME="UrlGrab"
UC_VERSION="1.0"

weechat.register (UC_NAME, UC_VERSION, "", "Url collector/launcher for weechat")
weechat.add_message_handler("privmsg", "urlGrabCheck")
weechat.add_command_handler("url", "urlGrabMain", 
  "Controls UrlGrab -> '/url help' for usage")

def urlGrabPrint(message):
    weechat.prnt("-[%s]- %s" % ( UC_NAME, message ) )

class WeechatSetting:
    def __init__(self, name, default, description = "" ):
        self.name = name
        self.default = default
        self.description = description
        test = weechat.get_plugin_config( name )
        if test is None or test == "":
            weechat.set_plugin_config( name, default )

class UrlGrabSettings:
    def __init__(self):
        self.settings = {
            'historysize':WeechatSetting('historysize', '10',
                "Number of URLs to keep per channel" ),
            'method':WeechatSetting('method', 'local',
                """Where to launch URLs
         If 'local', runs %localcmd%.
         If 'remote' runs the following command:
           `%remotessh% %remotehost% %remotecmd`"""),
            'localcmd':WeechatSetting('localcmd', 'firefox %s',
                """Command to launch local URLs.  '%s' becomes the URL.
         Default 'firefox %s'"""),
            'remotessh':WeechatSetting('remotessh', 'ssh -x',
                """Command (and arguments) to connect to a remote machine.
         Default 'ssh -x'"""),
            'remotehost':WeechatSetting('remotehost', 'localhost',
                """Hostname for remote launching
         Default 'localhost'"""),
            'remotecmd':WeechatSetting('remotecmd',
                'bash -c \"DISPLAY=:0.0 firefox %s\"',
                """Command to launch remote URLs.  '%s' becomes the URL.
         Default 'bash -c \"DISPLAY=:0.0 firefox %s\"'"""),
            'cmdlog':WeechatSetting('cmdlog',
                '~/.weechat/urllaunch.log',
                """File where command output is saved.  Overwritten each
         time an URL is launched
         Default '~/.weechat/urllaunch.log'""" )
            }

    def has(self, name):
        return self.settings.has_key(name)

    def names(self):
        return self.settings.keys()

    def description(self, name):
        return self.settings[name].description

    def set(self, name, value):
        # Force string values only
        if type(value) != type("a"):
            value = str(value)
        if name == "method":
            if value.lower() == "remote":
                weechat.set_plugin_config( 'method', "remote" )
            elif value.lower() == "local":
                weechat.set_plugin_config( 'method', "local" )
            else:
                raise ValueError( "\'%s\' is not \'local\' or \'remote\'" % value )
        elif name == "localcmd":
            if value.find( "%s" ) == -1:
                weechat.set_plugin_config( 'localcmd', value + " %s" )
            else:
                weechat.set_plugin_config( 'localcmd', value )
        elif name == "remotecmd":
            if value.find( "%s" ) == -1:
                weechat.set_plugin_config( 'remotecmd', value + " %s" )
            else:
                weechat.set_plugin_config( 'remotecmd', value )
        elif self.has(name):
            weechat.set_plugin_config( name, value )
            if name == "historysize":
                urlGrab.setHistorysize(int(value))
        else:
            raise KeyError( name )

    def get(self, name):
        if self.has(name):
            return weechat.get_plugin_config(name)
        else:
            raise KeyError( name )

    def prnt(self, name, verbose = True):
        weechat.prnt( " %s = %s" % (name.ljust(11), self.get(name)) )
        if verbose:
            weechat.prnt( "  -> %s" % (self.settings[name].description) )

    def prntall(self):
        for key in self.names():
            self.prnt(key, verbose = False)

    def createCmdList(self, url):
        if weechat.get_plugin_config( 'method' ) == 'remote':
            tmplist = weechat.get_plugin_config( 'remotessh' ).split(" ")
            tmplist.append(weechat.get_plugin_config( 'remotehost' ))
            tmplist.append(weechat.get_plugin_config( 'remotecmd' ) % (url))
        else:
            tmplist = (weechat.get_plugin_config( 'localcmd' ) % (url) ).split(" ")
        return tmplist

class UrlGrabber:
    def __init__(self, historysize):
        # init
        self.urls = {}
        self.historysize = 5
        # control
        self.setHistorysize(historysize)

    def setHistorysize(self, count):
        if count > 1:
            self.historysize = count

    def getHistorysize(self):
        return self.historysize

    def addUrl(self, url, channel, server):
        # check for server
        if not self.urls.has_key(server):
            self.urls[server] = {}
        # check for chan
        if not self.urls[server].has_key(channel):
            self.urls[server][channel] = []
        # add url
        if url in self.urls[server][channel]:
            self.urls[server][channel].remove(url)
        self.urls[server][channel].insert(0, url)
        # removing old urls
        while len(self.urls[server][channel]) > self.historysize:
            self.urls[server][channel].pop()

    def hasIndex( self, index, channel, server ):
        return self.urls.has_key(server) and \
                self.urls[server].has_key(channel) and \
                len(self.url[server][channel]) >= index

    def hasChannel( self, channel, server ):
        return self.urls.has_key(server) and \
                self.urls[server].has_key(channel)

    def hasServer( self, server ):
        return self.urls.has_key(server)

    def getUrl(self, index, channel, server):
        url = ""
        if self.urls.has_key(server):
            if self.urls[server].has_key(channel):
                if len(self.urls[server][channel]) >= index:
                    url = self.urls[server][channel][index-1]
        return url
        

    def prnt(self, channel, server):
        found = True
        if self.urls.has_key(server):
            if self.urls[server].has_key(channel):
                urlGrabPrint(channel + "@" +  server)
                if len(self.urls[server][channel]) > 0:
                    i = 1
                    for url in self.urls[server][channel]:
                        weechat.prnt(" --> " + str(i) + " : " + url)
                        i += 1
                else:
                    found = False
            elif channel == "*":
                for channel in self.urls[server].keys():
                  self.prnt(channel, server)
            else:
                found = False
        else:
            found = False

        if not found:
            urlGrabPrint(channel + "@" +  server + ": no entries")

def urlGrabParsemsg(command):
    infos = command.split(" ")
    chan = infos[2]
    message = " ".join(infos[3:])[1:]
    return (chan, message)

def urlGrabCheck(server, args):
    global urlGrab
    chan, message = urlGrabParsemsg(args)
    # Ignore output from 'tinyurl.py'
    if message.startswith( "[AKA] http://tinyurl.com" ):
        return weechat.PLUGIN_RC_OK
    # Check for URLs
    for word in message.split(" "):
        if word[0:7] == "http://" or \
           word[0:8] == "https://" or \
           word[0:6] == "ftp://":
            urlGrab.addUrl(word, chan, server)
    # check for any dead children and clean them up
    while True:
        try:
            mypid, status = os.waitpid(0, os.WNOHANG)        
        except:
            break
        else:
            if mypid <= 0:
                break
    return weechat.PLUGIN_RC_OK

def urlGrabOpen(index, channel = None):
    global urlGrab, urlGrabSettings

    server = weechat.get_info("server")
    if channel is None or channel == "":
        channel = weechat.get_info("channel")
    
    if channel == "":
        urlGrabPrint( "No current channel, you must specify one" )
    elif not urlGrab.hasChannel( channel, server ):
        urlGrabPrint("No URL found - Invalid channel")
    else:
        if index <= 0:
            urlGrabPrint("No URL found - Invalid index")
            return
        url = urlGrab.getUrl(index, channel, server)
        if url == "":
            urlGrabPrint("No URL found - Invalid index")
        else:
            urlGrabPrint("loading %s %sly" % (url, urlGrabSettings.get("method")))
            logfile = os.path.expanduser( urlGrabSettings.get( 'cmdlog' ) )

            argl = urlGrabSettings.createCmdList( url )
            dout = open(logfile, "w")
            dout.write( "UrlGrab: Running '%s'\n" % (" ".join(argl)) )
            dout.close()
            try:
                childpid = os.fork()
            except:
                urlGrabPrint("Fork failed!")
            if childpid == 0:
                # in the child- Detach from tty and Exec the command
                logfile = os.path.expanduser( urlGrabSettings.get( 'cmdlog' ) )
                din = open("/dev/null", "r")
                dout = open(logfile, "a")
                try:
                    # Redirect IO for the child
                    os.dup2(din.fileno(), 0)
                    os.dup2(dout.fileno(), 1)
                    os.dup2(dout.fileno(), 2)
                except:
                    dout.write( "UrlGrab: IO Redirection failed\n" )
                    dout.close()
                    din.close()
                    sys.exit(1)
                try:
                    # Actually run the command
                    os.execvp( argl[0], argl )
                except:
                    dout.write( "UrlGrab: Exec failed" )
                    dout.close()
                    din.close()
                    sys.exit(1)
            else:
                # In the parent - Don't wait now, wait later.
                return

def urlGrabList( args ):
    global urlGrab
    channel = ""
    if len(args) == 0:
        channel = weechat.get_info("channel")
    else:
        channel = args[0]
        
    if channel == "" or channel == "all":
        channel = "*"
    urlGrab.prnt(channel, weechat.get_info("server"))
        
def urlGrabHelp():
    weechat.prnt("")
    urlGrabPrint("Help")
    weechat.prnt(" Usage : ")
    weechat.prnt("    /url help")
    weechat.prnt("        -> display this help")
    weechat.prnt("    /url list [channel]")
    weechat.prnt("        -> display list of recorded urls in the specified channel")
    weechat.prnt("           If no channel is given, lists the current channel")
    weechat.prnt("    /url set [name [[=] value]]")
    weechat.prnt("        -> set or get one of the parameters")
    weechat.prnt("    /url n [channel]")
    weechat.prnt("        -> launch the nth url in `/url list`")
    weechat.prnt("           or the nth url in the specified channel")
    weechat.prnt("")

def urlGrabMain(server, args):
    largs = args.split(" ")
    #strip spaces
    while '' in largs:
        largs.remove('')
    while ' ' in largs:
        largs.remove(' ')
    if len(largs) == 0:
        urlGrabHelp()
    else:
        if largs[0] == 'help':
            urlGrabHelp()
        elif largs[0] == 'list':
            urlGrabList( largs[1:] )
        elif largs[0] == 'set':
            try:
                if (len(largs) == 1):
                    urlGrabPrint( "Available settings:" )
                    urlGrabSettings.prntall()
                elif (len(largs) == 2):
                    name = largs[1]
                    urlGrabPrint( "Get %s" % name )
                    urlGrabSettings.prnt( name )
                elif (len(largs) > 2):
                    name = largs[1]
                    value = None
                    if( largs[2] != "="):
                        value = " ".join(largs[2:])
                    elif( largs > 3 and largs[2] == "=" ):
                        value = " ".join(largs[3:])
                    urlGrabPrint( "set %s = \'%s\'" % (name, value) )
                    if value is not None:
                        try:
                            urlGrabSettings.set( name, value )
                            urlGrabSettings.prnt( name, verbose=False )
                        except ValueError, msg:
                            weechat.prnt( "  Failed: %s" % msg )
                    else:
                        weechat.prnt( "  Failed: No value given" )
            except KeyError:
                weechat.prnt( "  Failed: Unrecognized parameter '%s'" % name )
        else:
            try:
                no = int(largs[0])
                if len(largs) > 1:
                    urlGrabOpen(no, largs[1])
                else:
                    urlGrabOpen(no)
            except ValueError:
                urlGrabPrint( "Unknown command '%s'.  Try '/url help' for usage" % largs[0])
    return weechat.PLUGIN_RC_OK

# Initialize global variables
urlGrabSettings = UrlGrabSettings()
urlGrab = UrlGrabber( urlGrabSettings.get('historysize') )

Generated by  Doxygen 1.6.0   Back to index