I've put together another small set of patches for asciilifeform's logotron1. Some of the changes are small adjustments I've been running on my copy for a while now, a few are necessary updates for working with the Pest network, and lastly there's a more critical fix for a bug that was discovered recently by a member in #asciilifeform. I'll start with that one because it's the most entertaining.
Bot Recursion
The fun starts here2, when verisimilitude (wot: verisimilitude) figured out how to exploit a bug in the log bot to cause an infinite loop of line echos between two bots sitting in the same channel. The bot was easily patched by simply returning early in eat_logline
, after saving the line, if the line came from another bot. The list of bots already existed as a knob in the config but was previously only used for muting the colors of bot log lines in the www display.
Another small change in this patch is the is_pest
flag in the config, which the bot now uses to determine which regex to use when parsing log lines. This was useful for me now, since I have a bot each in both dulapnet and pestnet, and will be useful for others who want to also run a bot in a pestnet.
1 | diff -uNr a/logotron/bot.py b/logotron/bot.py |
2 | |
3 | |
4 | |
5 | ############################################################################## |
6 | |
7 | # Version. If changing this program, always set this to same # as in MANIFEST |
8 | -Ver = 689331 |
9 | +Ver = 719633 |
10 | |
11 | ## As of version 689331, this program will NOT work with Freenode !!! |
12 | |
13 | |
14 | TX_Delay = float(cfg.get("tcp", "t_delay")) |
15 | Servers = [x.strip() for x in cfg.get("irc", "servers").split(',')] |
16 | Port = int(cfg.get("irc", "port")) |
17 | + Is_Pest = int(cfg.get("irc", "is_pest")) |
18 | Nick = cfg.get("irc", "nick") |
19 | Pass = cfg.get("irc", "pass") |
20 | Channels = [x.strip() for x in cfg.get("irc", "chans").split(',')] |
21 | SkipInitLn = int(cfg.get("irc", "skip_init_lines")) |
22 | Discon_TO = int(cfg.get("irc", "disc_t")) |
23 | Prefix = cfg.get("control", "prefix") |
24 | + Bots = [x.strip() for x in cfg.get("control", "bots").split(',')]3 |
25 | # DBism: |
26 | DB_Name = cfg.get("db", "db_name") |
27 | DB_User = cfg.get("db", "db_user") |
28 | |
29 | save_line(datetime.now(), channel, Nick, False, message) |
30 | |
31 | |
32 | -# Standard incoming IRC line (excludes fleanode liquishit, etc) |
33 | -irc_line_re = re.compile("""^:([^!]+)\!\S+\s+PRIVMSG\s+\#(\S+)\s+\:(.*)""") |
34 | +# Standard incoming IRC (or PestNet) line (excludes fleanode liquishit, etc) |
35 | +if (Is_Pest): |
36 | + irc_line_re = re.compile("""^:(\S+)\s+PRIVMSG\s+\#(\S+)\s+\:(.*)""") |
37 | +else: |
38 | + irc_line_re = re.compile("""^:([^!]+)\!\S+\s+PRIVMSG\s+\#(\S+)\s+\:(.*)""") |
39 | |
40 | # The '#' prevents interaction via PM, this is not a PM-able bot. |
41 | |
42 | |
43 | # First, add the line to the log: |
44 | save_line(datetime.now(), chan, user, action, text) |
45 | |
46 | + # End here if the line came from another bot |
47 | + if user in Bots: |
48 | + return |
49 | + |
50 | # Then, see if the line was a command for this bot: |
51 | if text.startswith(Prefix): |
52 | cmd = text.partition(Prefix)[2].strip() |
53 | diff -uNr a/logotron/nsabot.conf b/logotron/nsabot.conf |
54 | |
55 | |
56 | |
57 | [irc] |
58 | servers = irc.dulap.xyz |
59 | port = 6667 |
60 | +# If the bot is on a Pest network, set to 1, otherwise 0 |
61 | +is_pest = 0 |
62 | |
63 | # Bot's nick (change to yours, as with all knobs) |
64 | nick = snsabot |
65 | |
66 | |
67 | [control] |
68 | # Command Trigger for IRC bot |
69 | -prefix = !q |
70 | +prefix = YOUR_BOT_TRIGGER |
71 | + |
72 | +# Other people's bots (for www colouration and bot rebellion suppression) |
73 | +bots = dulapbot, bitbot, bitdashbot, gribble, atcbot, punkbot, []bot, assbot, a111, deedbot, deedBot, deedbot-, feedbot, auctionbot, lobbesbot, snsabot, watchglass, trbexplorer, lekythion, sourcerer, ossabot, ericbot, sonofawitch, btcinfobot, BusyBot, drunkbot, spykedbot, pehbot, BingoBot, pokarBot, scoopbot, scoopbot_revived, ozbot, mpexbot |
74 | |
75 | [logotron] |
76 | # The current era. |
77 | |
78 | |
79 | css_file = classic.css |
80 | |
81 | -# Other people's bots (for colouration strictly) |
82 | -bots = gribble, atcbot, punkbot, []bot, assbot, a111, deedbot, deedBot, deedbot-, feedbot, auctionbot, lobbesbot, snsabot, watchglass, trbexplorer, lekythion, sourcerer, ossabot, ericbot, sonofawitch, btcinfobot, BusyBot, drunkbot, spykedbot, pehbot, oglafbot, BingoBot, pokarBot, scoopbot, scoopbot_revived, ozbot, mpexbot |
83 | - |
84 | # Days of inactivity after which chan is hidden by default |
85 | days_hide = 14 |
86 | |
87 | diff -uNr a/logotron/reader.py b/logotron/reader.py |
88 | |
89 | |
90 | |
91 | Nick = cfg.get("irc", "nick") |
92 | Channels = [x.strip() for x in cfg.get("irc", "chans").split(',')] |
93 | OldChans = [x.strip() for x in cfg.get("irc", "oldchans").split(',')] |
94 | - Bots = [x.strip() for x in cfg.get("logotron", "bots").split(',')] |
95 | + Bots = [x.strip() for x in cfg.get("control", "bots").split(',')] |
96 | Bots.append(Nick) # Add our own bot to the bot list |
97 | # DBism: |
98 | DB_Name = cfg.get("db", "db_name") |
Postgres Auto-Reconnect
This patch just formalizes the fix I added to my bot to deal with the recurring postgres connection timeouts4. Despite only 50% of logotron operators5 having this problem I still feel it's useful to have in the main branch since it adds a layer of robustness that wasn't previously there.
Minor Tweaks and Fixes to the Web View
This last patch contains a small set of fixes/tweaks that I've been running on my copy for a while now. From the release notes:
- Fix the
target
attribute on links. Hyperlinks were being rendered withtarget="\'_blank\'"
instead oftarget="_blank"
, resulting in links opening in the same new tab rather than each in its own new tab. - Reduce "last active" timestamp resolution in the channel selector menu. Channels last active more than a day ago won't show minutes and channels last active > 100 days ago won't show hours. E.g. "1d 5h ago" instead of "1d 5h 24m ago" and "100d ago" instead of "100d 12h 14m ago".
- Applicable to pestnet channels, hide hearsay annotations in the normal view. The full handle, including the hearsay annotation, can now be seen on hover as part of the
title
text. - Fix a bug in classic.css, introduced in 700821, which broke search term highlighting in the search results page.
And the prettyprinted diff for convenience:
1 | diff -uNr a/logotron/reader.py b/logotron/reader.py |
2 | |
3 | |
4 | |
5 | |
6 | if days != 0: |
7 | last_time_txt += '%dd ' % days |
8 | - if hours != 0: |
9 | + if hours != 0 and days < 100: |
10 | last_time_txt += '%dh ' % hours |
11 | - if minutes != 0: |
12 | + if minutes != 0 and days == 0: |
13 | last_time_txt += '%dm' % minutes |
14 | |
15 | last_time_url = "{0}{1}{2}/{3}#{4}".format( |
16 | |
17 | |
18 | # Format ordinary links: |
19 | payload = re.sub(stdlinks_re, |
20 | - r'<a href="\1" target=\'_blank\'>\1</a>', payload) |
21 | + r'<a href="\1" target="_blank">\1</a>', payload) |
22 | |
23 | # Now also format [link][text] links : |
24 | payload = re.sub(boxlinks_re, |
25 | - r'<a href="\1" target=\'_blank\'>\2</a>', payload) |
26 | + r'<a href="\1" target="_blank">\2</a>', payload) |
27 | |
28 | # For ancient logs strictly: substitute orig. link with our logger : |
29 | if l['era'] < 3: |
30 | |
31 | speaker = l['speaker'] |
32 | separator = ":" |
33 | |
34 | + # temporary hack to remove pest hearsay annotations |
35 | + speaker_short = re.split('\\[.*?\\]', speaker)[0] |
36 | + |
37 | if showchan: |
38 | - speaker = '<small>(' + l['chan'] + ')</small> ' + speaker |
39 | + speaker_short = '<small>(' + l['chan'] + ')</small> ' + speaker_short |
40 | |
41 | # If 'action', annotate: |
42 | if l['self']: |
43 | separator = "" |
44 | payload = "<i>" + payload + "</i>" |
45 | - speaker = "<i>" + speaker + "</i>" |
46 | + speaker_short = "<i>" + speaker_short + "</i>" |
47 | |
48 | # HTMLize the given line : |
49 | s = ("<div id='{0}' class='logline {6}{5}'>" |
50 | - "<a class='nick' title='{2}'" |
51 | - " href=\"{3}\">{1}</a>{7} {4}</div>").format(l['idx'], |
52 | + "<a class='nick' title='{1} @ {2}'" |
53 | + " href=\"{3}\">{8}</a>{7} {4}</div>").format(l['idx'], |
54 | speaker, |
55 | l['t'], |
56 | line_url(l), |
57 | payload, |
58 | bot, |
59 | dclass, |
60 | - separator) |
61 | + separator, |
62 | + speaker_short) |
63 | return s |
64 | |
65 | # Make above callable from inside htm templater: |
66 | diff -uNr a/logotron/static/classic.css b/logotron/static/classic.css |
67 | |
68 | |
69 | |
70 | float:right; |
71 | } |
72 | |
73 | -.loglines div.highlight { |
74 | +.loglines div.highlight, |
75 | +.loglines span.highlight { |
76 | background: yellow; |
77 | } |
Patches and Signatures
fix_bot_recursion.kv.vpatch (sig)
add_pg_reconnect.kv.vpatch (sig)
minor_reader_tweaks.kv.vpatch (sig)
- Also available here. [↩]
- If you click on some of the logs.bitdash.io/asciilifeform links and notice they don't take you to the same log line that the bot echoed at the time it's because my db was three lines out of sync from when I inadvertently broke my bot with a system clock update. I have since added the missing lines but as a result any logs.bitdash.io/asciilifeform references during that period will be off by three lines. Check bitbot's echo to see what was the intended reference at the time. [↩]
- As part of this patch I moved the
bots
config line from underneathlogotron
tocontrol
, as this seemed more appropriate now that it controls bot behavior rather than just CSS classes in the display. [↩] - Which has been working great. I've not had to restart the bot once because of a lost postgres connection and I'm no longer afraid of using my own logotron's search bar out of concern that it'll cause a long query and disconnect the bot. [↩]
- That 50% being me. As far as I know asciilifeform and I are the only two people currently running this particular logotoron, and his postgres seems to behave better than mine. [↩]
[...] New Logotoron Patches: Bug Fixes and Enhancements [...]