Skip to content

Instantly share code, notes, and snippets.

@Taiiwo
Last active September 7, 2017 07:13
Show Gist options
  • Save Taiiwo/006ef1d3fdc7c75f62a2ea861b00da94 to your computer and use it in GitHub Desktop.
Save Taiiwo/006ef1d3fdc7c75f62a2ea861b00da94 to your computer and use it in GitHub Desktop.

Weechat Catchup Script

A weechat script that catches you up to the chat using RSVP(Rapid serial visual presentation); a statistically proven way of scanning text with higher speeds and retention rate than regular reading.

There are many apps and services out there that let you read articles, text files, and other media using a method of RSVP, but none of them are really convenient for reading IRC messages. I found that if it takes me too long to read the entire backlog, I'll never get to the present time before being distracted by some other thing; so I made this.

Here's a GIF of it working.

animated gif of plugin in action

ToDo

  • Make settings part of the weechat config
  • Optimize the padding to ignore the first letter if it's a vowel
  • Colour usernames
  • Make it possible to lengthen the duration of usernames (Simple solution: Write the username twice)
  • Possibly wrap the username in square brackets for distiction
  • Think of a way to separate multiple message by the same person. Possibly by full stop?
  • Determine the number of unread lines in an intelligent way
  • Implement hotkeys to increase or decrease speed on the fly
  • Implement hotkey to go back a message for if you look away or something
  • Make the code nicer. I couldn't be bothered not to use globals. It's only a script.
  • Make this repository a more weechat-friendly format
  • End world hunger
import weechat
import time
import re
import os
import urllib
weechat.register("speed_catchup", "Taiiwo", "1.0", "GPL3",
"Catch up with the chat by speed reading", "", "")
total_pad = 10
interval = 250
tail_num = 5
vowels = re.compile("[aiueoy]")
global_words = False
reading_buffer = ""
# Get the last n lines from a file
def tail(f, lines=1, _buffer=4098):
# place holder for the lines found
lines_found = []
# block counter will be multiplied by buffer
# to get the block size from the end
block_counter = -1
# loop until we find X lines
while len(lines_found) < lines:
try:
f.seek(block_counter * _buffer, os.SEEK_END)
except IOError: # either file is too small, or too many lines requested
f.seek(0)
lines_found = f.readlines()
break
lines_found = f.readlines()
# we found enough lines, get out
if len(lines_found) > lines:
break
# decrement the block counter to get the
# next X bytes
block_counter -= 1
return lines_found[-lines:]
# Pad a word so the first vowel is centered (Or center if no vowel)
def pad(word):
# look for the first vowel in the word
match = vowels.search(word)
# if a vowel exists
if match:
# center the word around the found vowel
optimal_center = match.span()[0]
else:
# center the word normally
optimal_center = len(word) / 2
# colour the central letter of the word
word = word[:optimal_center] + \
weechat.color("red") + \
word[optimal_center] + \
weechat.color("chat") + \
word[optimal_center + 1:]
# apply padding so the optimal_center is in the center
pad = total_pad - optimal_center
return " " * pad + word
# Sets the input box every tick
def word_loop(data, remaining_calls):
global global_words, reading_buffer
# only run if the word list is not empty
if global_words:
# write the next word in the queue to the input box
weechat.buffer_set(reading_buffer, "input", global_words[0])
# remove the word from the queue
global_words.pop(0)
return weechat.WEECHAT_RC_OK
# Speed read a string
def speed_read(string):
global global_words, reading_buffer
# set the reading buffer to the current buffer
reading_buffer = weechat.current_buffer()
# pad out all the words
words = [pad(word) for word in string.split()]
# if loop has already been initiated
if isinstance(global_words, list):
# add to existing word list
global_words += words + [""]
else:
# create word list and begin loop
global_words = words + [""]
hook = weechat.hook_timer(interval, 0, 0, "word_loop", "")
# Main plugin function. (Run on /catchup)
def catchup(data, buffer, args):
# get log file location of buffer
log_file = weechat.string_eval_path_home(
"%h/logs/" + weechat.buffer_get_string(
buffer, "full_name"
) + ".weechatlog",
{},
{},
{}
)
# get tail num
if args and args.isdigit():
tail_num_arg = int(args)
else:
tail_num_arg = False
# tail the log file
with open(log_file, "rb") as f:
text = tail(f, lines=tail_num_arg if tail_num_arg else tail_num)
# process the log file lines
backlog = ""
for line in text:
# remove everything after the first tab (truncating the date)
backlog += line[line.find("\t"):] + "\n"
# speed read the log to the user
speed_read(backlog)
return weechat.WEECHAT_RC_OK
# Add hook for /catchup
hook = weechat.hook_command("catchup", "catchup with messages from this buffer",
"[number of lines]",
"",
"",
"catchup",
""
)
def key_pressed(data, signal, signal_data):
global global_words
if global_words and len(global_words) > 1:
global_words = [""]
return weechat.WEECHAT_RC_OK
hook = weechat.hook_signal("key_combo_default", "key_pressed", "")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment