New Logotoron Patches: Bug Fixes and Enhancements

January 22nd, 2022

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 --- a/logotron/bot.py 048fcb73260b4b85459e1e8ca4529df95a1e4d6898b74a8259c38a690aeb0840cf77fef9fd5f16445287f0d4091e18ddf7e2da478e9cb09db157f16eeb4c85ec
3 +++ b/logotron/bot.py fa93d94c684695b4ac20f57b9580d2e1faf9e82e83145eaca7a9ff2d1130d5e296c0e1007d771ba7cd17b4dde33d4da2c6975af8d9e3a29412dcd3f5d013f25e
4 @@ -14,7 +14,7 @@
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 @@ -64,12 +64,14 @@
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 @@ -214,8 +216,11 @@
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 @@ -527,6 +532,10 @@
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 --- a/logotron/nsabot.conf b2117eaa3fbedff592b133635a84997b236d781936c9e8473d771ad67ab4e20a4a36062c9449b4ac0ee0fc7cd4c2bced405105a250378bd3a6a5658de05c3a30
55 +++ b/logotron/nsabot.conf ad5f570234ff7f7afa4e2d43669c36e502c820a6645c5f241a255e608ce897133ca31caf2d26269204d63ed7b49c793589987581aba503dad6c3a64a502849cd
56 @@ -6,6 +6,8 @@
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 @@ -40,7 +42,10 @@
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 @@ -67,9 +72,6 @@
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 --- a/logotron/reader.py c249c7a987199fd5e0356b13c36401654b4df837e238c8c91c10c3a988b91ba6a19c908f7e33298e559ef40b058e6c67ec6e9da4bb8539c8153aa6cbf17bbabc
89 +++ b/logotron/reader.py 3b02f186daaee1b4fe93a53324fbd3c09924538f15d607c01cdb1381434ed9155671d5f239065ed431630ce3c6585c14dfcd8f3443a56189300a10d6f6288ee3
90 @@ -39,7 +39,7 @@
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 with target="\'_blank\'" instead of target="_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 --- a/logotron/reader.py 3b02f186daaee1b4fe93a53324fbd3c09924538f15d607c01cdb1381434ed9155671d5f239065ed431630ce3c6585c14dfcd8f3443a56189300a10d6f6288ee3
3 +++ b/logotron/reader.py 3447a168ff1b14190b284952a9f4cd7619cae304f1a61169463bf677db6f3898d4a354fd8154b46ba59cb8adea177d97108f9e96d83eda33c48fa27ac9623b13
4 @@ -185,9 +185,9 @@
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 @@ -265,11 +265,11 @@
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 @@ -300,26 +300,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 --- a/logotron/static/classic.css 15af7c20d831947a9333ceb510fa80acb38d983601c8d05c7cb21d5d06829a3ef7feaac18821b614c7fca148651f4849c98dd50455cafa30313a79e697975893
68 +++ b/logotron/static/classic.css 091c56349c022f5616f0b9b6e95d6e7bf4420ef4e40b10587756ffc342d580ef8684104c7fb69347fd4e07e8ca37d541e5ac7841219fa8856ceaa7246f422a73
69 @@ -98,6 +98,7 @@
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)

  1. Also available here. []
  2. 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. []
  3. As part of this patch I moved the bots config line from underneath logotron to control, as this seemed more appropriate now that it controls bot behavior rather than just CSS classes in the display. []
  4. 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. []
  5. 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. []
« Adding Postgres Auto-Reconnect to the Logotron's IRC Bot
Building TRB on a 2022 Vintage Musl Gentoo »

One Comment

Leave a Reply

*
*

You can use the following HTML tags in your comment: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>