367 lines
12 KiB
Python
367 lines
12 KiB
Python
|
import time
|
||
|
|
||
|
import windows
|
||
|
import widgets
|
||
|
import chaninfo
|
||
|
|
||
|
from conf import conf
|
||
|
|
||
|
textareas = {}
|
||
|
if 'font' in conf:
|
||
|
textareas['font'] = conf['font']
|
||
|
if 'bg_color' in conf:
|
||
|
textareas['bg'] = conf['bg_color']
|
||
|
if 'fg_color' in conf:
|
||
|
textareas['fg'] = conf['fg_color']
|
||
|
|
||
|
widgets.set_style("view", textareas)
|
||
|
widgets.set_style("nicklist", textareas)
|
||
|
|
||
|
#copied pretty directly from something that was probably copied from wine sources
|
||
|
def RGBtoHSL(r, g, b):
|
||
|
maxval = max(r, g, b)
|
||
|
minval = min(r, g, b)
|
||
|
|
||
|
luminosity = ((maxval + minval) * 240 + 255) // 510
|
||
|
|
||
|
if maxval == minval:
|
||
|
saturation = 0
|
||
|
hue = 160
|
||
|
else:
|
||
|
delta = maxval - minval
|
||
|
|
||
|
if luminosity <= 120:
|
||
|
saturation = ((maxval+minval)//2 + delta*240) // (maxval + minval)
|
||
|
else:
|
||
|
saturation = ((150-maxval-minval)//2 + delta*240) // (150-maxval-minval)
|
||
|
|
||
|
#sigh..
|
||
|
rnorm = (delta//2 + maxval*40 - r*40)//delta
|
||
|
gnorm = (delta//2 + maxval*40 - g*40)//delta
|
||
|
bnorm = (delta//2 + maxval*40 - b*40)//delta
|
||
|
|
||
|
if r == maxval:
|
||
|
hue = bnorm-gnorm
|
||
|
elif g == maxval:
|
||
|
hue = 80+rnorm-bnorm
|
||
|
else:
|
||
|
hue = 160+gnorm-rnorm
|
||
|
hue = hue % 240
|
||
|
return hue, saturation, luminosity
|
||
|
|
||
|
#copied from the same place
|
||
|
def huetoRGB(hue, mid1, mid2):
|
||
|
hue = hue % 240
|
||
|
|
||
|
if hue > 160:
|
||
|
return mid1
|
||
|
elif hue > 120:
|
||
|
hue = 160 - hue
|
||
|
elif hue > 40:
|
||
|
return mid2
|
||
|
return ((hue * (mid2 - mid1) + 20) // 40) + mid1
|
||
|
|
||
|
#this too
|
||
|
def HSLtoRGB(hue, saturation, luminosity):
|
||
|
if saturation != 0:
|
||
|
if luminosity > 120:
|
||
|
mid2 = saturation + luminosity - (saturation * luminosity + 120)//240
|
||
|
else:
|
||
|
mid2 = ((saturation + 240) * luminosity + 120)//240
|
||
|
|
||
|
mid1 = luminosity * 2 - mid2
|
||
|
|
||
|
return tuple((huetoRGB(hue+x, mid1, mid2) * 255 + 120) // 240 for x in (80,0,-80))
|
||
|
else:
|
||
|
value = luminosity * 255 // 240
|
||
|
return value, value, value
|
||
|
|
||
|
def gethashcolor(string):
|
||
|
h = hash(string)
|
||
|
rgb = HSLtoRGB(h%241, 100-h//241%61, 90)
|
||
|
return "%02x%02x%02x" % rgb
|
||
|
|
||
|
#take an event e and trigger the highlight event if necessary
|
||
|
def hilight_text(e):
|
||
|
if not hasattr(e, 'Highlight'):
|
||
|
e.Highlight = []
|
||
|
core.events.trigger('Highlight', e)
|
||
|
|
||
|
#hilight own nick
|
||
|
def onHighlight(e):
|
||
|
lowertext = e.text.lower()
|
||
|
for word in conf.get('highlight_words', []) + [e.network.me] + e.network.nicks:
|
||
|
lowerword = word.lower()
|
||
|
pos = lowertext.find(lowerword, 0)
|
||
|
while pos != -1:
|
||
|
e.Highlight.append((pos, pos+len(word)))
|
||
|
pos = lowertext.find(lowerword, pos+1)
|
||
|
|
||
|
def prefix(e):
|
||
|
return time.strftime(conf.get('timestamp', ''))
|
||
|
|
||
|
def getsourcecolor(e):
|
||
|
address = getattr(e, "address", "")
|
||
|
if address:
|
||
|
if e.network.me == e.source:
|
||
|
e.network._my_address = address
|
||
|
elif e.network.me == e.source:
|
||
|
address = getattr(e.network, "_my_address", "")
|
||
|
if '@' in address:
|
||
|
address = address.split('@')[1]
|
||
|
if not address:
|
||
|
address = e.source
|
||
|
return "\x04%s" % gethashcolor(address)
|
||
|
|
||
|
def format_source(e):
|
||
|
highlight = getattr(e, "Highlight", "") and '\x02' or ''
|
||
|
return "%s\x04%s%s" % (highlight, getsourcecolor(e), e.source)
|
||
|
|
||
|
def format_info_source(e):
|
||
|
if e.source == e.network.me:
|
||
|
return "\x04%sYou" % (getsourcecolor(e))
|
||
|
else:
|
||
|
return "\x04%s%s" % (getsourcecolor(e), e.source)
|
||
|
|
||
|
def address(e):
|
||
|
#if e.source != e.network.me:
|
||
|
# return "%s " % info_in_brackets(e.address)
|
||
|
#else:
|
||
|
# return ""
|
||
|
return ""
|
||
|
|
||
|
def text(e):
|
||
|
if e.text:
|
||
|
#return " %s" % info_in_brackets(e.text)
|
||
|
return ": \x0F%s" % e.text
|
||
|
else:
|
||
|
return ""
|
||
|
|
||
|
def info_in_brackets(text):
|
||
|
return "(\x044881b6%s\x0F)" % text
|
||
|
|
||
|
def pretty_time(secs):
|
||
|
times = (
|
||
|
#("years", "year", 31556952),
|
||
|
("weeks", "week", 604800),
|
||
|
("days", "day", 86400),
|
||
|
("hours", "hour", 3600),
|
||
|
("minutes", "minute", 60),
|
||
|
("seconds", "second", 1),
|
||
|
)
|
||
|
if secs == 0:
|
||
|
return "0 seconds"
|
||
|
result = ""
|
||
|
for plural, singular, amount in times:
|
||
|
n, secs = divmod(secs, amount)
|
||
|
if n == 1:
|
||
|
result = result + " %s %s" % (n, singular)
|
||
|
elif n:
|
||
|
result = result + " %s %s" % (n, plural)
|
||
|
return result[1:]
|
||
|
|
||
|
def onText(e):
|
||
|
hilight_text(e)
|
||
|
color = getsourcecolor(e)
|
||
|
to_write = prefix(e)
|
||
|
if e.network.me == e.target: # this is a pm
|
||
|
if e.window.id == e.network.norm_case(e.source):
|
||
|
to_write += "\x02<\x0F%s\x0F\x02>\x0F " % (format_source(e))
|
||
|
else:
|
||
|
to_write += "\x02*\x0F%s\x0F\x02*\x0F " % (format_source(e))
|
||
|
else:
|
||
|
if e.window.id == e.network.norm_case(e.target):
|
||
|
to_write += "\x02<\x0F%s\x0F\x02>\x0F " % (format_source(e))
|
||
|
else:
|
||
|
to_write += "\x02<\x0F%s:%s\x0F\x02>\x0F " % (format_source(e), e.target)
|
||
|
to_write += e.text
|
||
|
|
||
|
if e.Highlight:
|
||
|
e.window.write(to_write, widgets.HILIT)
|
||
|
else:
|
||
|
e.window.write(to_write, widgets.TEXT)
|
||
|
|
||
|
def onOwnText(e):
|
||
|
color = getsourcecolor(e)
|
||
|
to_write = prefix(e)
|
||
|
if e.window.id == e.network.norm_case(e.target):
|
||
|
to_write += "\x02<\x0F%s\x0F\x02>\x0F %s" % (format_source(e), e.text)
|
||
|
else:
|
||
|
to_write += "%s->\x0F \x02*\x0F%s\x0F\x02*\x0F %s" % (color, e.target, e.text)
|
||
|
|
||
|
e.window.write(to_write)
|
||
|
|
||
|
def onAction(e):
|
||
|
hilight_text(e)
|
||
|
color = color = getsourcecolor(e)
|
||
|
to_write = "%s\x02*\x0F %s\x0F %s" % (prefix(e), format_source(e), e.text)
|
||
|
|
||
|
if e.Highlight:
|
||
|
e.window.write(to_write, widgets.HILIT)
|
||
|
else:
|
||
|
e.window.write(to_write, widgets.TEXT)
|
||
|
|
||
|
def onOwnAction(e):
|
||
|
color = getsourcecolor(e)
|
||
|
to_write = "%s\x02*\x0F %s\x0F %s" % (prefix(e), format_source(e), e.text)
|
||
|
|
||
|
e.window.write(to_write)
|
||
|
|
||
|
def onNotice(e):
|
||
|
hilight_text(e)
|
||
|
color = getsourcecolor(e)
|
||
|
to_write = prefix(e)
|
||
|
if e.network.me == e.target: # this is a pm
|
||
|
to_write += "\x02-\x0F%s\x0F\x02-\x0F " % (format_source(e))
|
||
|
else:
|
||
|
to_write += "\x02-\x0F%s:%s\x0F\x02-\x0F " % (format_source(e), e.target)
|
||
|
to_write += e.text
|
||
|
|
||
|
e.window.write(to_write, (e.Highlight and widgets.HILIT) or widgets.TEXT)
|
||
|
|
||
|
def onOwnNotice(e):
|
||
|
color = getsourcecolor(e)
|
||
|
to_write = "%s-> \x02-\x02%s\x0F\x02-\x0F %s" % (prefix(e), e.target, e.text)
|
||
|
|
||
|
e.window.write(to_write)
|
||
|
|
||
|
def onCtcp(e):
|
||
|
color = getsourcecolor(e)
|
||
|
to_write = "%s\x02[\x02%s\x0F\x02]\x0F %s" % (prefix(e), format_source(e), e.text)
|
||
|
|
||
|
if not e.quiet:
|
||
|
e.window.write(to_write)
|
||
|
|
||
|
def onCtcpReply(e):
|
||
|
color = getsourcecolor(e)
|
||
|
to_write = "%s%s--- %s reply from %s:\x0F %s" % (prefix(e), color, e.name.capitalize(), format_source(e), ' '.join(e.args))
|
||
|
|
||
|
window = windows.manager.get_active()
|
||
|
if window.network != e.network:
|
||
|
window = windows.get_default(e.network)
|
||
|
window.write(to_write, widgets.TEXT)
|
||
|
|
||
|
def onJoin(e):
|
||
|
if e.source == e.network.me:
|
||
|
to_write = "%s%s %sjoin %s" % (prefix(e), format_info_source(e), address(e), e.target)
|
||
|
else:
|
||
|
to_write = "%s%s %sjoins %s" % (prefix(e), format_info_source(e), address(e), e.target)
|
||
|
|
||
|
e.window.write(to_write)
|
||
|
|
||
|
def onPart(e):
|
||
|
if e.source == e.network.me:
|
||
|
to_write = "%s%s leave %s%s" % (prefix(e), format_info_source(e), e.target, text(e))
|
||
|
else:
|
||
|
to_write = "%s%s leaves %s%s" % (prefix(e), format_info_source(e), e.target, text(e))
|
||
|
|
||
|
e.window.write(to_write)
|
||
|
|
||
|
def onKick(e):
|
||
|
if e.source == e.network.me:
|
||
|
to_write = "%s%s kick %s%s" % (prefix(e), format_info_source(e), e.target, text(e))
|
||
|
else:
|
||
|
to_write = "%s%s kicks %s%s" % (prefix(e), format_info_source(e), e.target, text(e))
|
||
|
|
||
|
e.window.write(to_write, (e.target == e.network.me and widgets.HILIT) or widgets.EVENT)
|
||
|
|
||
|
def onMode(e):
|
||
|
if e.source == e.network.me:
|
||
|
to_write = "%s%s set mode:\x0F %s" % (prefix(e), format_info_source(e), e.text)
|
||
|
else:
|
||
|
to_write = "%s%s sets mode:\x0F %s" % (prefix(e), format_info_source(e), e.text)
|
||
|
|
||
|
e.window.write(to_write)
|
||
|
|
||
|
def onQuit(e):
|
||
|
to_write = "%s%s leaves%s" % (prefix(e), format_info_source(e), text(e))
|
||
|
|
||
|
for channame in chaninfo.channels(e.network):
|
||
|
if chaninfo.ison(e.network, channame, e.source):
|
||
|
window = windows.get(windows.ChannelWindow, e.network, channame, core)
|
||
|
if window:
|
||
|
window.write(to_write)
|
||
|
|
||
|
def onNick(e):
|
||
|
color = getsourcecolor(e)
|
||
|
if e.source == e.network.me:
|
||
|
to_write = "%s%sYou are now known as %s" % (prefix(e), color, e.target)
|
||
|
else:
|
||
|
to_write = "%s%s%s is now known as %s" % (prefix(e), color, e.source, e.target)
|
||
|
|
||
|
if e.source == e.network.me:
|
||
|
for window in windows.get_with(core.manager, network=e.network):
|
||
|
window.write(to_write)
|
||
|
else:
|
||
|
for channame in chaninfo.channels(e.network):
|
||
|
if chaninfo.ison(e.network,channame,e.source):
|
||
|
window = windows.get(windows.ChannelWindow, e.network, channame)
|
||
|
if window:
|
||
|
window.write(to_write)
|
||
|
|
||
|
def onTopic(e):
|
||
|
if e.source == e.network.me:
|
||
|
to_write = "%s%s set topic:\x0F %s" % (prefix(e), format_info_source(e), e.text)
|
||
|
else:
|
||
|
to_write = "%s%s sets topic:\x0F %s" % (prefix(e), format_info_source(e), e.text)
|
||
|
|
||
|
e.window.write(to_write)
|
||
|
|
||
|
def onRaw(e):
|
||
|
if not e.quiet:
|
||
|
if e.msg[1].isdigit():
|
||
|
if e.msg[1] == '332':
|
||
|
window = windows.get(windows.ChannelWindow, e.network, e.msg[3], core) or e.window
|
||
|
window.write(
|
||
|
"%sTopic on %s is: %s" %
|
||
|
(prefix(e), e.msg[3], e.text)
|
||
|
)
|
||
|
|
||
|
elif e.msg[1] == '333':
|
||
|
window = windows.get(windows.ChannelWindow, e.network, e.msg[3], core) or e.window
|
||
|
window.write(
|
||
|
"%sTopic on %s set by %s at time %s" %
|
||
|
(prefix(e), e.msg[3], e.msg[4], time.ctime(int(e.msg[5])))
|
||
|
)
|
||
|
|
||
|
elif e.msg[1] == '329': #RPL_CREATIONTIME
|
||
|
pass
|
||
|
|
||
|
elif e.msg[1] == '311': #RPL_WHOISUSER
|
||
|
e.window.write("* %s is %s@%s * %s" % (e.msg[3], e.msg[4], e.msg[5], e.msg[7]))
|
||
|
|
||
|
elif e.msg[1] == '312': #RPL_WHOISSERVER
|
||
|
e.window.write("* %s on %s (%s)" % (e.msg[3], e.msg[4], e.msg[5]))
|
||
|
|
||
|
elif e.msg[1] == '317': #RPL_WHOISIDLE
|
||
|
e.window.write("* %s has been idle for %s" % (e.msg[3], pretty_time(int(e.msg[4]))))
|
||
|
if e.msg[5].isdigit():
|
||
|
e.window.write("* %s signed on %s" % (e.msg[3], time.ctime(int(e.msg[5]))))
|
||
|
|
||
|
elif e.msg[1] == '319': #RPL_WHOISCHANNELS
|
||
|
e.window.write("* %s on channels: %s" % (e.msg[3], e.msg[4]))
|
||
|
|
||
|
elif e.msg[1] == '330': #RPL_WHOISACCOUNT
|
||
|
#this appears to conflict with another raw, so if there's anything weird about it,
|
||
|
# we fall back on the default
|
||
|
if len(e.msg) == 6 and not e.msg[4].isdigit() and not e.msg[5].isdigit():
|
||
|
e.window.write("* %s %s %s" % (e.msg[3], e.msg[5], e.msg[4]))
|
||
|
else:
|
||
|
e.window.write("* %s" % ' '.join(e.msg[3:]))
|
||
|
|
||
|
else:
|
||
|
e.window.write("* %s" % ' '.join(e.msg[3:]))
|
||
|
elif e.msg[1] == 'ERROR':
|
||
|
e.window.write("Error: %s" % e.text)
|
||
|
|
||
|
def onDisconnect(e):
|
||
|
to_write = '%s* Disconnected' % prefix(e)
|
||
|
if e.error:
|
||
|
to_write += ' (%s)' % e.error
|
||
|
|
||
|
for window in windows.get_with(network=e.network):
|
||
|
if isinstance(window, windows.StatusWindow):
|
||
|
window.write(to_write, widgets.TEXT)
|
||
|
else:
|
||
|
window.write(to_write, widgets.EVENT)
|