Skip to content

Instantly share code, notes, and snippets.

@SmileyChris
Created January 6, 2016 02:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save SmileyChris/a9cd2d4235b72cf425b5 to your computer and use it in GitHub Desktop.
Save SmileyChris/a9cd2d4235b72cf425b5 to your computer and use it in GitHub Desktop.
Hexchat plugin to filter joins/parts except for recent talkers. Put it in ~/.config/hexchat/addons
__module_name__ = 'Filter'
__module_version__ = '1.0.custom'
__module_description__ = 'Filters join/part/voice messages'
import hexchat
import collections
from time import time
last_seen = {} # For each entry: the key is the user's nickname, the entry
# is a list: element 0: last seen time
# element 1: boolean for if the user has spoken
recent_scrollback = collections.deque(maxlen=30)
# Keep track of users in the recent scrollback (irregardless of
# time)
user_timeout = 600 # If the user hasn't spoken for this amount of seconds, his
# join/part messages won't be shown
halt = False
def human_readable(s):
deltas = [
("seconds", int(s)%60),
("minutes", int(s/60)%60),
("hours", int(s/60/60)%24),
("days", int(s/24/60/60)%30),
("months", int(s/30/24/60/60)%12),
("years", int(s/12/30/24/60/60))
]
if s <= 0:
return "just now"
tarr = ['%d %s' % (d[1], d[1] > 1 and d[0] or d[0][:-1])
for d in reversed(deltas) if d[1]]
return " ".join(tarr[:2]) + " ago"
def new_msg(word, word_eol, event, attrs):
"""
Handle normal messages.
Unless this is the first user's message since they joined, the message will
not be altered. Otherwise, a '(logged in Xs ago)' message will be appended.
"""
global halt
if halt is True:
return
user = hexchat.strip(word[0])
user_last_seen = last_seen.get(user)
# Update or add the user to the last_seen dict.
last_seen[user] = [time(), True]
recent_scrollback.append(user)
if not user_last_seen or user_last_seen[1]:
# The user has spoken before (or their join time is unknown), nothing
# else to do.
return
# First time the user has spoken, let us know when they logged in.
time_diff = time() - user_last_seen[0]
word[1] += " \00307(logged in %s)" % human_readable(time_diff)
halt = True
hexchat.emit_print(event, *word)
halt = False
return hexchat.EAT_ALL
def filter_msg(word, word_eol, event, attrs):
"""
Filter join, part and voice messages.
"""
user = hexchat.strip(word[0])
# If the user just joined, add him to the dict and mark him as such
#if 'Join' in userdata:
if event == "Join":
if user not in last_seen:
last_seen[user] = [time(), False]
return hexchat.EAT_ALL
# If the user changed his nick, check if we've been tracking him before
# and transfer his stats if so. Otherwise, add him to the dict.
#elif 'Nick' in userdata:
elif event == "Change Nick":
old_user = user
user = hexchat.strip(word[1])
if old_user in last_seen:
last_seen[user] = last_seen.pop(old_user)
if old_user in recent_scrollback:
users = list(recent_scrollback)
for i, scrollback_user in enumerate(users):
if scrollback_user != old_user:
continue
users[i] = user
recent_scrollback.clear()
recent_scrollback.extend(users)
if event in ("Channel Voice", "Channel DeVoice"):
# The user being voiced is actually who we're interested in.
user = hexchat.strip(word[1])
# If the user talked in the recent scrollback, allow it (irregardless of
# time).
if user not in recent_scrollback:
# If the user logged in before we did (no entry of him yet), don't
# display his part messages
if user not in last_seen:
return hexchat.EAT_ALL
# If the user has never spoken, or has spoken too long ago, eat his
# part or join messages.
spoken, last_message = last_seen[user]
if not spoken or last_message + user_timeout < time():
return hexchat.EAT_ALL
hooks_new = ["Your Message", "Channel Message", "Channel Msg Hilight",
"Your Action", "Channel Action", "Channel Action Hilight"]
hooks_filter = ["Join", "Change Nick", "Part", "Part with Reason", "Quit",
"Channel Voice", "Channel DeVoice"]
# hook_print_attrs is used for compatibility with my other scripts,
# since priorities are hook specific
for hook in hooks_new:
hexchat.hook_print_attrs(hook, new_msg, hook, hexchat.PRI_HIGH)
for hook in hooks_filter:
hexchat.hook_print_attrs(hook, filter_msg, hook, hexchat.PRI_HIGH)
print("\00304" + __module_name__ + " successfully loaded.\003")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment