448 lines
16 KiB
Python
448 lines
16 KiB
Python
#
|
|
# 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') )
|