Skip to content

Instantly share code, notes, and snippets.

@rezemika
Last active August 8, 2017 09:24
Show Gist options
  • Save rezemika/07cc0d28882bcc6c1a0e386e5e8ba98c to your computer and use it in GitHub Desktop.
Save rezemika/07cc0d28882bcc6c1a0e386e5e8ba98c to your computer and use it in GitHub Desktop.
A simple tool to convert Weechat screenshots to pretty quotes.
#!/usr/bin/env python3
"""
Outputs to stdin a quote-like text from a Weechat screen.
How to use this script?
./weechat_converter.py --help
--aligned Aligns all reply starts
--file FILE A file containing the text to convert
If no argument is provided, the script will use stdin. So, you can
pipe text to it, or run it and paste the text to the console,
then hit Ctrl+D.
Please make sure that all lines follow the same format. Start the
copy at beginning of a line and end it at the end of another.
Here is a typical line in the input file.
21:16:41 rezemika | Hey! │
Set the variable "gap_before_time" to True to allow parsing when
each line begins with a gap. Example:
│ │20:03:34 rezemika | A simple example. │
^ Here is the gap.
Set "bold_nickname" to surround nicknames with '**' (markdown).
Output example:
<rezemika> Hello world!
<rezemika est maintenant connu sous le nom azerty>
<azerty a quitté le canal (Ping timeout: 255 seconds)>
<rezemika a rejoint le canal>
Script published under AGPLv3 licence by rezemika.
"""
import argparse
import sys
import re
# TODO : Store translatable strings in a dict.
# Settings
gap_before_time = False
DEBUG = False # Set to True to raise exception when fails to parse a line.
bold_nicknames = True
def parse_line(line):
if gap_before_time:
line = line.split('│')[2].split(' ', 1)[1]
else:
line = line.split('│')[0].split(' ', 1)[1]
line = [e.strip() for e in line.split('|')]
return line
def normal(text):
quote = ""
lines = []
for i, line in enumerate(text):
try:
temp_line = parse_line(line)
except Exception as e:
if DEBUG:
raise e
else:
continue
if temp_line[0] == '-->': # Join.
nickname = temp_line[1].split()[0]
special_line = "{} a rejoint le canal".format(nickname)
lines.append((special_line, ''))
elif temp_line[0] == '<--': # Leave.
nickname = temp_line[1].split()[0]
reason = re.findall("\(([^)]*)\)[^(]*$", temp_line[1])[0]
special_line = "{} a quitté le canal ({})".format(nickname, reason)
lines.append((special_line, ''))
elif temp_line[0] == '--':
if "maintenant connu sous le nom" in temp_line[1]:
if temp_line[1].startswith("Vous"):
lines.append((temp_line[1], ''))
else:
old_nickname = temp_line[1].split(' ', 1)[0]
new_nickname = temp_line[1].rsplit(' ', 1)[1]
special_line = "{} est maintenant connu sous le nom {}".format(old_nickname, new_nickname)
lines.append((special_line, ''))
else: # TODO : Handle.
continue
else:
try:
next_line = parse_line(text[i+1])
if not next_line[0]:
temp_line[1] += ' ' + next_line[1]
del(text[i+1])
except IndexError:
pass
lines.append(temp_line)
if bold_nicknames:
bold = '**'
else:
bold = ''
for i, line in enumerate(lines):
if line[1]:
quote += "{bold}<{}>{bold} {}".format(line[0], line[1], bold=bold)
else:
quote += "{bold}<{}>{bold}".format(line[0], bold=bold)
if i != len(lines)-1:
quote += '\n'
return quote
def aligned(text):
quote = ""
nicknames = set()
lines = []
i = 0
for line in text:
temp_line = parse_line(line)
if temp_line[0] == '-->': # Join.
nickname = temp_line[1].split()[0]
special_line = "{} a rejoint le canal".format(nickname)
lines.append((special_line, ''))
elif temp_line[0] == '<--': # Leave.
nickname = temp_line[1].split()[0]
reason = re.findall("\(([^)]*)\)[^(]*$", temp_line[1])[0]
special_line = "{} a quitté le canal ({})".format(nickname, reason)
lines.append((special_line, ''))
elif temp_line[0] == '--':
if "maintenant connu sous le nom" in temp_line[1]:
if temp_line[1].startswith("Vous"):
lines.append((temp_line[1], ''))
else:
old_nickname = temp_line[1].split(' ', 1)[0]
new_nickname = temp_line[1].rsplit(' ', 1)[1]
special_line = "{} est maintenant connu sous le nom {}".format(old_nickname, new_nickname)
lines.append((special_line, ''))
else: # TODO : Handle.
continue
else:
try:
if temp_line[0] not in nicknames:
nicknames.add(temp_line[0])
next_line = parse_line(text[i+1])
if not next_line[0]:
temp_line[1] += ' ' + next_line[1]
del(text[i+1])
except IndexError:
pass
lines.append(temp_line)
i += 1
if bold_nicknames:
bold = '**'
else:
bold = ''
for i, line in enumerate(lines):
spaces = ''
if line[0] != max(nicknames, key=len):
spaces = ' '*(len(max(nicknames, key=len))-len(line[0]))
quote += "{bold}<{}>{bold}{} {}".format(line[0], spaces, line[1], bold=bold)
if i != len(lines)-1:
quote += '\n'
return quote
if __name__ == '__main__':
parser = argparse.ArgumentParser(prog="weechat-converter")
parser.add_argument("--aligned", action="store_true", help="Aligns all reply starts")
parser.add_argument("--file", type=argparse.FileType('r'), help="A file containing the text to convert")
args = parser.parse_args()
if args.file:
text = args.file.readlines()
else:
text = sys.stdin.readlines()
if args.aligned:
sys.stdout.write(aligned(text) + '\n')
else:
sys.stdout.write(normal(text) + '\n')
exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment