diff options
Diffstat (limited to 'scripts/python/onattach.py')
-rw-r--r-- | scripts/python/onattach.py | 445 |
1 files changed, 0 insertions, 445 deletions
diff --git a/scripts/python/onattach.py b/scripts/python/onattach.py deleted file mode 100644 index d5117716e..000000000 --- a/scripts/python/onattach.py +++ /dev/null @@ -1,445 +0,0 @@ -# -*- encoding: iso-8859-1 -*- -# -# Copyright (c) 2006 by EgS <i@egs.name> -# -# 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 St, Fifth Floor, Boston, MA 02110-1301 USA -# - - -####################################################################### -# # -# This script enables the execution of events triggered commands # -# where the events are attach or detach of the screen weechat # -# is running in. # -# # -# Name: OnAttach # -# Licence: GPL v2 # -# Author: Marcus Eggenberger <i@egs.name> # -# # -# Usage: # -# /onattach or /ondetach to add new events # -# /screenevents to manage events # -# # -# use /help command for detailed information # -# # -# Changelog: # -# 0.5: added screen guessing to backup screen-detection # -# 0.4: fixed TypeError in weechat 0.1.9 # -# 0.3: now checking on startup if weechat runs in a screen # -# 0.2: added usage of get/set_plugin_config to store eventlist # -# 0.1: first version released # -# # -####################################################################### - - - -# ==================== -# Imports -# ==================== -import os -import sys - -# ==================== -# Constants -# ==================== -NAME = 'OnAttach' -VERSION = '0.5' -DESCRIPTION = "Executing commands on screen Attach/Detach" - -OFF = False -ON = True - -# ==================== -# Exceptions -# ==================== -class OnAttachError(Exception): - pass - -# ==================== -# Helpers -# ==================== -class WeePrint(object): - def write(self, text): - text = text.rstrip(' \0\n') # strip the null byte appended by pythons print - if text: - weechat.prnt(text,'') - -def getScreenByPpid(): - # the screen we are in should be our parents parent - # aka something like: - # SCREEN - # \_ -/bin/bash - # \_ weechat-curses - ppid = os.getppid() - - # get SCREEN pid - pipe = os.popen("ps o ppid= -p %d" % ppid) - screenpid = pipe.read().strip() - pipe.close() - - # check if screen pid really belongs to a screen - pipe = os.popen("ps o cmd= -p %s" % screenpid) - cmd = pipe.read().strip() - pipe.close() - - if 'screen' not in cmd.lower(): - raise OnAttachError - else: - return screenpid - -def getScreenByList(): - # checks if there is only one attached screen - # if so use: it! ;) - pipe = os.popen("screen -list | grep -i attached") - screens = pipe.read().strip() - pipe.close() - screens = screens.splitlines() - - if len(screens) > 1: - print "There are more then one screen currently attached." - print "Detach all other running screens and reload OnAttach" - print "to ensure correct screen detection." - raise OnAttachError - - try: - socket, status = screens[0].split() - except: - # thats no common screen list... - print "failed!" - raise OnAttachError - else: - print "Using screen %s" % socket - return socket - -def getScreenPid(): - try: - return getScreenByPpid() - except OnAttachError: - print "!!! Unable to determine screen by parentid!" - print "Trying to guess screen..." - return getScreenByList() - -def registerFunction(function): - # Register a python function as a commandhandler - # Function needs to be named like weeFunction and - # is bound to /function - # docstring is used for weechat help - functionname = function.__name__ # guess what :) - weecommand = functionname[3:].lower() # strip the wee - - doc = function.__doc__.splitlines() - arguments = doc[0] # First docstring line is the arguments string - description = doc[1][4:] - args_description = '\n'.join([line[4:] for line in doc[2:-1]]) # join rest and strip indentation - - if not function.func_defaults: # use args default value as template - template = '' - elif len(function.func_defaults) == 1: - template = function.func_defaults[0] - elif len(function.func_defaults) == 2: - template = func.func_defaults[1] - - weechat.add_command_handler(weecommand, functionname, description, arguments, args_description, template) - -def registerFunctions(): - functions = [function for name, function in globals().iteritems() if name.startswith('wee') and callable(function)] - for func in functions: - registerFunction(func) - -# ==================== -# Classes -# ==================== -class Event(object): - ESCAPECHAR = '\\' - SEPARATOR = ';' - - def __init__(self, delay, step, channel, server, command, activehigh=True): - self.delay = int(delay) - self.step = step - self.channel = channel - self.server = server - self.command = command - self.activestate = activehigh - self.reset() - - #@classmethod - def unserialize(cls, step, serial): - try: - # let's try the easy way :) - delay, channel, server, command, activestate = serial.split() - except ValueError: - # ok we got an escaped separator... :/ - data = serial.split(cls.SEPARATOR) - for i in range(len(data)): - if data[i].endswith(cls.ESCAPECHAR): - data[i+1] = data[i] + cls.SEPARATOR + data[i+1] - data = [item.replace(cls.ESCAPECHAR + cls.SEPARATOR, cls.SEPARATOR) for item in data if not item.endswith(cls.ESCAPECHAR)] - delay, channel, server, command, activestate = data - - - delay = int(delay) - activestate = activestate == 'True' - - return cls(delay, step, channel, server, command, activestate) - # lets go for 2.3 compatiblity - unserialize = classmethod(unserialize) - - #@property - def serialized(self): - data = [self.delay, self.channel, self.server, self.command, self.activestate] - data = [str(item).replace(self.SEPARATOR, self.ESCAPECHAR + self.SEPARATOR) for item in data] - return self.SEPARATOR.join(data) - # lets go for 2.3 compatiblity - serialized = property(serialized) - - def reset(self): - self.currentdelay = self.delay - self.fired = False - - def fire(self): - weechat.command(self.command, self.channel, self.server) - self.fired = True - - def stimulus(self, state): - if state != self.activestate: - self.reset() - else: - self.currentdelay -= self.step - if self.currentdelay <= 0 and not self.fired: - self.fire() - -class CheckStatus(object): - ESCAPECHAR = '\\' - SEPARATOR = '|' - - eventlist = [] - step = 5 - def __init__(self): - try: - self.screenpid = getScreenPid() - except OnAttachError: - raise - - # try to read config data - serializedEvents = weechat.get_plugin_config("events") - if not serializedEvents: - return - - events = serializedEvents.split(self.SEPARATOR) - for i in range(len(events)): - if events[i].endswith(self.ESCAPECHAR): - events[i+1] = events[i] + self.SEPARATOR + ss[i+1] - events = [event.replace(self.ESCAPECHAR + self.SEPARATOR, self.SEPARATOR) for event in events if not event.endswith(self.ESCAPECHAR)] - for event in events: - try: - self.eventlist.append(Event.unserialize(self.step, event)) - except: - print "Unable to unserialize event!" - print "Try to add the event manualy and save config again." - - def __call__(self, server="", args=""): - # check if the screen is attached or detatched - pipe = os.popen("screen -list | grep %s" % self.screenpid) - screenlist = pipe.read().strip() - pipe.close() - - if 'attached' in screenlist.lower(): - state = ON - elif 'detached' in screenlist.lower(): - state = OFF - else: - print "Unable to determine screen status" - return weechat.PLUGIN_RC_KO - - for event in self.eventlist: - event.stimulus(state) - - return weechat.PLUGIN_RC_OK - - def addEvent(self, delay, channel, server, command, activehigh=True): - event = Event(delay, self.step, channel, server, command, activehigh) - self.eventlist.append(event) - - def showEvents(self): - format = "%2s | %-10s | %-10s | %-15s | %-7s | %-2s %s" - separator = "---+------------+------------+-----------------+---------+----" - print separator - print format % ("ID", "Server", "Channel", "Command", "Delay", "on", "") - print separator - for i in range(len(self.eventlist)): - event = self.eventlist[i] - if event.activestate: - atde = 'AT' - else: - atde = 'DE' - - if event.fired: - fired = '*' - else: - fired = '' - print format % (i, event.server[:10], event.channel[:10], event.command[:15], "%3d sec" % event.delay, atde, fired) - print separator - - def save(self): - weechat.set_plugin_config("events",self.serialized) - - #@property - def serialized(self): - events = [str(event.serialized).replace(self.SEPARATOR, self.ESCAPECHAR + self.SEPARATOR) for event in self.eventlist] - return self.SEPARATOR.join(events) - # lets go for 2.3 compatiblity - serialized = property(serialized) - - def dropEvent(self, eventid): - del self.eventlist[eventid] - -# ==================== -# Functions -# ==================== -def addEvent(server, args, activehigh=True): - delay, channel, command = args.split(' ', 2) - delay = int(delay) - - channel = channel.strip("'\"") - checkStatus.addEvent(delay, channel, server, command, activehigh) - if activehigh: - atde = "at" - else: - atde = "de" - - print "Added %stach event '%s' for channel %s on network %s with %d seconds delay" % (atde, command, channel, server, delay) - -def weeOnAttach(server, args): - """delay channel command - Adds a command which is executed after attaching the screen - The command is executed <delay> seconds after the attach. - Use "" or '' as channel if the command should be executed in - the server buffer. - - Example: - /onattach 180 &bitlbee account on 0 - """ - try: - addEvent(server, args) - except: - weechat.command("/help onattach", "", server) - return 0 - else: - return 1 - -def weeOnDetach(server, args): - """delay channel command - Adds a command which is executed after detaching the screen - The command is executed <delay> seconds after the detach. - Use "" or '' as channel if the command should be executed in - the server buffer. - - Example: - /ondetach 180 &bitlbee account on 0 - """ - try: - addEvent(server, args, activehigh=False) - except: - weechat.command("/help onattach", "", server) - return 0 - else: - return 1 - -def weeScreenevents(server, args="show|save|drop"): - """show | save | drop eventid [eventid [...]] - shows, saves or drops events - show: - Shows all current active events - - save: - Saves current events permanently - - drop: - Delete event from onAttach/onDetach list. - Use /showevents to get eventid - """ - try: - action, args = args.split(' ',1) - except ValueError: - action = args.strip() - args = '' - - actions = {'show':showEvents, - 'drop':dropEvent, - 'save':saveEvents} - try: - action = actions[action] - except KeyError: - weechat.command("/help screenevents", "", server) - return 0 - else: - return action(server, args) - - - -def showEvents(server, args): - checkStatus.showEvents() - return 1 - -def dropEvent(server, args): - try: - eventids = [int(id) for id in args.split()] - except: - print "eventid musst be a number!" - return 0 - - eventids.sort() - eventids.reverse() - for eventid in eventids: - try: - checkStatus.dropEvent(eventid) - except: - print "Unable to drop Event %d" % eventid - return 0 - print "dropped %d events!" % len(eventids) - return 1 - -def saveEvents(server, args): - checkStatus.save() - return 1 - -# ==================== -# Let's Register! -# ==================== -if __name__ == '__main__': - try: - import weechat - except ImportError: - print "This script is to be loaded as PythonScript in WeeChat" - print "Get WeeChat now at: http://weechat.flashtux.org/" - import sys - sys.exit(10) - - # kick pythons print to weechat.prnt(msg, '') - sys.stdout = WeePrint() - weechat.register(NAME, VERSION, "", DESCRIPTION) - try: - checkStatus = CheckStatus() - except OnAttachError: - print "!!! Requirements for %s not met:" % NAME - print "!!! - WeeChat is not running in a screen or not able to get screen PID" - print "!!! --> Run WeeChat in a screen to fix the problem!" - else: - - weechat.add_timer_handler(checkStatus.step, "checkStatus") - - registerFunctions() - - |