Created
January 6, 2013 03:51
-
-
Save HarHar/4465095 to your computer and use it in GitHub Desktop.
A very sad attempt at translating terminal color codes to irc color codes on shell.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
# ============================================================================= | |
# shell.py (c) March 2006, 2009 by Kolter <[email protected]> | |
# | |
# Licence : GPL v2 | |
# Description : running shell commands in WeeChat | |
# Syntax : try /help shell to get some help on this script | |
# Precond : needs weechat >= 0.3.0 to run | |
# | |
# | |
# ### changelog ### | |
# | |
# * version 0.7, 2012-11-26, Sebastien Helleu <[email protected]>: | |
# - use hashtable for command arguments (for WeeChat >= 0.4.0) | |
# * version 0.6, 2012-11-21, Sebastien Helleu <[email protected]>: | |
# - call shell in hook_process (WeeChat >= 0.3.9.2 does not call shell any more) | |
# * version 0.5, 2011-10-01, Sebastien Helleu <[email protected]>: | |
# - add shell buffer | |
# * version 0.4, 2009-05-02, Sebastien Helleu <[email protected]>: | |
# - sync with last API changes | |
# * version 0.3, 2009-03-06, Sebastien Helleu <[email protected]>: | |
# - use of hook_process to run background process | |
# - add option -t <timeout> to kill process after <timeout> seconds | |
# - show process running, kill it with -kill | |
# * version 0.2, 2009-01-31, Sebastien Helleu <[email protected]>: | |
# - conversion to WeeChat 0.3.0+ | |
# * version 0.1, 2006-03-13, Kolter <[email protected]>: | |
# - first release | |
# | |
# ============================================================================= | |
import weechat, os, datetime | |
SCRIPT_NAME = 'shell' | |
SCRIPT_AUTHOR = 'Kolter' | |
SCRIPT_VERSION = '0.7' | |
SCRIPT_LICENSE = 'GPL2' | |
SCRIPT_DESC = 'Run shell commands in WeeChat' | |
SHELL_CMD = 'shell' | |
SHELL_PREFIX = '[shell] ' | |
cmd_hook_process = '' | |
cmd_command = '' | |
cmd_start_time = None | |
cmd_buffer = '' | |
cmd_shell_buffer = '' | |
cmd_stdout = '' | |
cmd_stderr = '' | |
cmd_send_to_buffer = '' | |
cmd_timeout = 0 | |
if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, | |
SCRIPT_DESC, '', ''): | |
weechat.hook_command( | |
SHELL_CMD, | |
'Running shell commands in WeeChat', | |
'[-o|-n] [-t seconds] <command> || -show || -kill', | |
' -o: send output to current buffer (simulate user entry ' | |
'with command output - dangerous, be careful when using this option)\n' | |
' -n: display output in a new empty buffer\n' | |
'-t seconds: auto-kill process after timeout (seconds) if process ' | |
'is still running\n' | |
' command: shell command or builtin like cd, getenv, setenv, unsetenv\n' | |
' -show: show running process\n' | |
' -kill: kill running process', | |
'-o|-n|-t|cd|getenv|setenv|unsetenv|-show||-kill -o|-n|-t|cd|getenv|setenv|unsetenv', | |
'shell_cmd', '') | |
import webcolors | |
def closest_colour(requested_colour): | |
min_colours = {} | |
for key, name in webcolors.css3_hex_to_names.items(): | |
r_c, g_c, b_c = webcolors.hex_to_rgb(key) | |
rd = (r_c - requested_colour[0]) ** 2 | |
gd = (g_c - requested_colour[1]) ** 2 | |
bd = (b_c - requested_colour[2]) ** 2 | |
min_colours[(rd + gd + bd)] = name | |
return min_colours[min(min_colours.keys())] | |
def get_colour_name(requested_colour): | |
try: | |
closest_name = actual_name = webcolors.rgb_to_name(requested_colour) | |
except ValueError: | |
closest_name = closest_colour(requested_colour) | |
actual_name = None | |
return actual_name, closest_name | |
def shell_init(): | |
"""Initialize some variables.""" | |
global cmd_hook_process, cmd_command, cmd_start_time, cmd_buffer, cmd_stdout, cmd_stderr | |
cmd_hook_process = '' | |
cmd_command = '' | |
cmd_start_time = None | |
cmd_buffer = '' | |
cmd_stdout = '' | |
cmd_stderr = '' | |
def shell_set_title(): | |
"""Set title on shell buffer (with working directory).""" | |
global cmd_shell_buffer | |
if cmd_shell_buffer: | |
weechat.buffer_set(cmd_shell_buffer, 'title', | |
'%s.py %s | "q": close buffer | Working dir: %s' % (SCRIPT_NAME, SCRIPT_VERSION, os.getcwd())) | |
def shell_process_cb(data, command, rc, stdout, stderr): | |
"""Callback for hook_process().""" | |
global cmd_hook_process, cmd_buffer, cmd_stdout, cmd_stderr, cmd_send_to_buffer | |
cmd_stdout += stdout | |
cmd_stderr += stderr | |
if int(rc) >= 0: | |
if cmd_stdout: | |
lines = cmd_stdout | |
out = '' | |
a = False | |
l = 0 | |
r, g, b = '', '', '' | |
for c in lines: | |
if a == False: | |
if c == '\x1b': | |
a = True | |
l = 0 | |
continue | |
out += c | |
else: | |
if c == ';': l += 1; continue | |
if c == 'm': | |
l = 0 | |
a = False | |
if r == '': r = '0' | |
if g == '': g = '0' | |
if b == '': b = '0' | |
t1, t2 = get_colour_name((int(r), int(g), int(b))) | |
if t1 != None: | |
cn = t1 | |
elif t2 != None: | |
cn = t2 | |
else: | |
continue | |
colortable = {'white': '0', 'aqua': '11', 'black': '1', 'blue': '2', 'midnightblue': '2', 'yellow': '8', 'orange': '7', 'purple': '6', 'green': '3', 'lime': '9', 'red': '4', 'brown': '5', 'maroon': '5', 'royal': '12', 'deeppink': '13', 'pink': '13', 'fuchsia': '13'} | |
if cn in colortable: | |
out += chr(3) + colortable[cn] | |
continue | |
elif cn.strip('light') in colortable: | |
out += chr(3) + colortable[cn.strip('light')] | |
continue | |
elif cn.strip('dark') in colortable: | |
out += chr(3) + colortable[cn.strip('dark')] | |
continue | |
elif cn.strip('deep') in colortable: | |
out += chr(3) + colortable[cn.strip('deep')] | |
continue | |
else: | |
out += '{' + cn + '}' | |
continue | |
if l == 1: | |
r += c | |
elif l == 2: | |
g += c | |
elif l == 3: | |
b += c | |
lines = out.split('\n') | |
if cmd_send_to_buffer == 'current': | |
for line in lines: | |
if line: | |
weechat.command(cmd_buffer, '%s' % line) | |
else: | |
if cmd_send_to_buffer != 'new': | |
weechat.prnt(cmd_buffer, '%sCommand "%s" (rc %d), stdout:' | |
% (SHELL_PREFIX, data, int(rc))) | |
for line in lines: | |
if line: | |
weechat.prnt(cmd_buffer, ' \t%s' % line) | |
if cmd_stderr: | |
lines = cmd_stderr.split('\n') | |
if cmd_send_to_buffer == 'current': | |
for line in lines: | |
if line: | |
weechat.command(cmd_buffer, '%s' % line) | |
else: | |
if cmd_send_to_buffer != 'new': | |
weechat.prnt(cmd_buffer, '%s%sCommand "%s" (rc %d), stderr:' | |
% (weechat.prefix('error'), SHELL_PREFIX, data, int(rc))) | |
for line in lines: | |
if line: | |
weechat.prnt(cmd_buffer, '%s%s' % (weechat.prefix('error'), line)) | |
cmd_hook_process = '' | |
shell_set_title() | |
return weechat.WEECHAT_RC_OK | |
def shell_show_process(buffer): | |
"""Show running process.""" | |
global cmd_command, cmd_start_time | |
if cmd_hook_process: | |
weechat.prnt(buffer, '%sprocess running: "%s" (started on %s)' | |
% (SHELL_PREFIX, cmd_command, cmd_start_time.ctime())) | |
else: | |
weechat.prnt(buffer, '%sno process running' % SHELL_PREFIX) | |
def shell_kill_process(buffer): | |
"""Kill running process.""" | |
global cmd_hook_process, cmd_command | |
if cmd_hook_process: | |
weechat.unhook(cmd_hook_process) | |
weechat.prnt(buffer, '%sprocess killed (command "%s")' % (SHELL_PREFIX, cmd_command)) | |
shell_init() | |
else: | |
weechat.prnt(buffer, '%sno process running' % SHELL_PREFIX) | |
def shell_chdir(buffer, directory): | |
"""Change working directory.""" | |
if not directory: | |
if os.environ.has_key('HOME'): | |
directory = os.environ['HOME'] | |
try: | |
os.chdir(directory) | |
except: | |
weechat.prnt(buffer, '%san error occured while running command "cd %s"' % (SHELL_PREFIX, directory)) | |
else: | |
weechat.prnt(buffer, '%schdir to "%s" ok, new path: %s' % (SHELL_PREFIX, directory, os.getcwd())) | |
shell_set_title() | |
def shell_getenv(buffer, var): | |
"""Get environment variable.""" | |
global cmd_send_to_buffer | |
var = var.strip() | |
if not var: | |
weechat.prnt(buffer, '%swrong syntax, try "getenv VAR"' % (SHELL_PREFIX)) | |
return | |
value = os.getenv(var) | |
if value == None: | |
weechat.prnt(buffer, '%s$%s is not set' % (SHELL_PREFIX, var)) | |
else: | |
if cmd_send_to_buffer == 'current': | |
weechat.command(buffer, '$%s=%s' % (var, os.getenv(var))) | |
else: | |
weechat.prnt(buffer, '%s$%s=%s' % (SHELL_PREFIX, var, os.getenv(var))) | |
def shell_setenv(buffer, expr): | |
"""Set an environment variable.""" | |
global cmd_send_to_buffer | |
expr = expr.strip() | |
lexpr = expr.split('=') | |
if (len(lexpr) < 2): | |
weechat.prnt(buffer, '%swrong syntax, try "setenv VAR=VALUE"' % (SHELL_PREFIX)) | |
return | |
os.environ[lexpr[0].strip()] = '='.join(lexpr[1:]) | |
if cmd_send_to_buffer != 'current': | |
weechat.prnt(buffer, '%s$%s is now set to "%s"' % (SHELL_PREFIX, lexpr[0], '='.join(lexpr[1:]))) | |
def shell_unsetenv(buffer, var): | |
"""Remove environment variable.""" | |
var = var.strip() | |
if not var: | |
weechat.prnt(buffer, '%swrong syntax, try "unsetenv VAR"' % (SHELL_PREFIX)) | |
return | |
if os.environ.has_key(var): | |
del os.environ[var] | |
weechat.prnt(buffer, '%s$%s is now unset' % (SHELL_PREFIX, var)) | |
else: | |
weechat.prnt(buffer, '%s$%s is not set' % (SHELL_PREFIX, var)) | |
def shell_exec(buffer, command): | |
"""Execute a command.""" | |
global cmd_hook_process, cmd_command, cmd_start_time, cmd_buffer | |
global cmd_stdout, cmd_stderr, cmd_send_to_buffer, cmd_timeout | |
if cmd_hook_process: | |
weechat.prnt(buffer, | |
'%sanother process is running! (use "/%s -kill" to kill it)' | |
% (SHELL_PREFIX, SHELL_CMD)) | |
return | |
if cmd_send_to_buffer == 'new': | |
weechat.prnt(buffer, '-->\t%s%s$ %s%s' | |
% (weechat.color('chat_buffer'), os.getcwd(), weechat.color('reset'), command)) | |
weechat.prnt(buffer, '') | |
args = command.split(' ') | |
if args[0] == 'cd': | |
shell_chdir(buffer, ' '.join(args[1:])) | |
elif args[0] == 'getenv': | |
shell_getenv (buffer, ' '.join(args[1:])) | |
elif args[0] == 'setenv': | |
shell_setenv (buffer, ' '.join(args[1:])) | |
elif args[0] == 'unsetenv': | |
shell_unsetenv (buffer, ' '.join(args[1:])) | |
else: | |
shell_init() | |
cmd_command = command | |
cmd_start_time = datetime.datetime.now() | |
cmd_buffer = buffer | |
version = weechat.info_get("version_number", "") or 0 | |
if int(version) >= 0x00040000: | |
cmd_hook_process = weechat.hook_process_hashtable('sh', { 'arg1': '-c', 'arg2': command }, | |
cmd_timeout * 1000, 'shell_process_cb', command) | |
else: | |
cmd_hook_process = weechat.hook_process("sh -c '%s'" % command, cmd_timeout * 1000, 'shell_process_cb', command) | |
def shell_input_buffer(data, buffer, input): | |
"""Input callback on shell buffer.""" | |
global cmd_send_to_buffer | |
if input in ('q', 'Q'): | |
weechat.buffer_close(buffer) | |
return weechat.WEECHAT_RC_OK | |
cmd_send_to_buffer = 'new' | |
weechat.prnt(buffer, '') | |
command = weechat.string_input_for_buffer(input) | |
shell_exec(buffer, command) | |
return weechat.WEECHAT_RC_OK | |
def shell_close_buffer(data, buffer): | |
"""Close callback on shell buffer.""" | |
global cmd_shell_buffer | |
cmd_shell_buffer = '' | |
return weechat.WEECHAT_RC_OK | |
def shell_new_buffer(): | |
"""Create shell buffer.""" | |
global cmd_shell_buffer | |
cmd_shell_buffer = weechat.buffer_search('python', 'shell') | |
if not cmd_shell_buffer: | |
cmd_shell_buffer = weechat.buffer_new('shell', 'shell_input_buffer', '', 'shell_close_buffer', '') | |
if cmd_shell_buffer: | |
shell_set_title() | |
weechat.buffer_set(cmd_shell_buffer, 'localvar_set_no_log', '1') | |
weechat.buffer_set(cmd_shell_buffer, 'time_for_each_line', '0') | |
weechat.buffer_set(cmd_shell_buffer, 'input_get_unknown_commands', '1') | |
weechat.buffer_set(cmd_shell_buffer, 'display', '1') | |
return cmd_shell_buffer | |
def shell_cmd(data, buffer, args): | |
"""Callback for /shell command.""" | |
global cmd_send_to_buffer, cmd_timeout | |
largs = args.split(' ') | |
# strip spaces | |
while '' in largs: | |
largs.remove('') | |
while ' ' in largs: | |
largs.remove(' ') | |
cmdbuf = buffer | |
if len(largs) == 0: | |
shell_new_buffer() | |
else: | |
if largs[0] == '-show': | |
shell_show_process(cmdbuf) | |
elif largs[0] == '-kill': | |
shell_kill_process(cmdbuf) | |
else: | |
cmd_send_to_buffer = '' | |
cmd_timeout = 0 | |
while largs: | |
if largs[0] == '-o': | |
cmd_send_to_buffer = 'current' | |
largs = largs[1:] | |
continue | |
if largs[0] == '-n': | |
cmd_send_to_buffer = 'new' | |
cmdbuf = shell_new_buffer() | |
largs = largs[1:] | |
continue | |
if largs[0] == '-t' and len(largs) > 2: | |
cmd_timeout = int(largs[1]) | |
largs = largs[2:] | |
continue | |
break | |
if len(largs) > 0: | |
shell_exec(cmdbuf, ' '.join(largs)) | |
return weechat.WEECHAT_RC_OK |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment