tree checksum vpatch file split hunks

all signers: lobbes asciilifeform diana_coman

antecedents: uniturds_etc.kv line_wraps.kv raw_line_fix.kv uptimefix_bye_cache.kv irssi_format.kv

press order:

logotron_genesis.kvasciilifeform diana_coman
multsel_and_datefix.kvasciilifeform diana_coman
raw_line_export.kvasciilifeform diana_coman
rle_errata.kvasciilifeform diana_coman
irssi2tmsr.kvasciilifeform diana_coman
uniturds_etc.kvasciilifeform diana_coman
line_wraps.kvasciilifeform diana_coman
znc2tmsr_etc.kvasciilifeform diana_coman lobbes
uptimefix_bye_cache.kvasciilifeform diana_coman lobbes
raw_line_fix.kvasciilifeform diana_coman lobbes
irssi_format.kvasciilifeform diana_coman
sept_fixes.kvasciilifeform diana_coman

patch:

- DBBA91F83102533D1E4C0C7EFA6C861054C4A9C7CE713F92813916F9A5692592A8D0E2EFBB8EBE0D3C87DDD7477581228E59D3A9D52DABFDE0A0D18FC13E4BF8
+ 4F46CCC238FF725712306588453E7A1CE18E29D69ED1589988E1E276DC7A6D0F1F0DE31A86C47D08541E68150B83C55177499FA4C704453AC8C4EDF372495DAA
logotron/MANIFEST.TXT
(9 . 3)(9 . 4)
5 593779 uptimefix_bye_cache lobbes "Fix in bot.py for global time_last_conn. Remove Cache from reader.py. Small README fix re: create database."
6 594463 raw_line_fix lobbes "Fix to raw line export in reader.py to remove semi-colon from right side of nick on action lines"
7 595435 irssi_format diana_coman "Updates the irssi2tmsr converter to work on out-of-the-box irssi format. Updated README file too with example of format."
8 596907 sept_fixes asciilifeform "Several small improvements to bot and reader."
- A6BFA0BC96BDE13236F34D83BFF5D8053E73031BE0BA1AAFE29C84F8E38F475470919E785D2A9AFA6E134F02A6C64908E14BE04C89465C8CFCF5958FBA23B13B
+ 1F4326CF8D7A7AC9CCD54DA9CCC56B4C5EEF008245933A2905A87978AABDB27D438C8BDD2430275AE75C5CE2A4D335DF9FBD1F671A69D046B12F7CF2F57B4AE9
logotron/README.txt
(92 . 3)(92 . 29)
13 (4) WWW: Links in log lines now open in new browser tab (a la Phf's log)
14 (5) WWW: Can now be loaded 'in reverse gear', http://...../log?rev=1
15 (6) WWW: 'Random' knob, takes reader to an arbitrary moment in past log.
16
17 ###############
18 Sep. 28 Update:
19 ###############
20
21 (1) Bot: incorporated reconnector fixes.
22 (2) Bot: 'seen', 'seen-all', and 'version' knobs implemented.
23 (3) WWW: up/down arrows for mouse-driven operation on pocket comps
24 (4) WWW: double-quotes prevent breakup of search query
25 (Note: still needs improvement to force matching on word boundaries)
26 (5) WWW: demarkation of "action" lines
27 (6) WWW: Raw 'Tape" knob:
28
29 e.g. http://logs.nosuchlabs.com/tape?istart=1937934&iend=1937941
30 returns:
31
32 trilema;1937934;1569444908;asciilifeform;achtung panzers! piz pipe down ?!
33 trilema;1937935;1569444920;diana_coman;seems so
34 trilema;1937936;1569444957;asciilifeform;paging BingoBoingo !
35 trilema;1937937;1569444974;diana_coman;well, apparetly he was connected from piz too, lol
36 trilema;1937938;1569444982;diana_coman;ossasepia.com (pizarro) is down too, yes
37 trilema;1937939;1569445010;asciilifeform;dulap unreachable for 1st time since year+ ago when bb elbowed the mains cord
38 trilema;1937940;1569445073;diana_coman;apparently back on
39 trilema;1937941;1569445079;diana_coman;wb BingoBoingo !
40
41 Still needs a variant of 'eater' that will eat these.
- 19772A67F431072DE4C51C6600D860C8CBB77F4E5172F4C20F43078565EDA7C07C599E165EE588552741A703CBD13B1043D6C2850858CBE2CC9D3F5249F54C8F
+ 7980970A1D40B7A348A8FED795896D0CFA4568E3B4464768A0EA118EFDE16645BCDF2E934BA1ED42BC1D7708BCCB9EF28F0645C13CBDC80754D00D8DD47A6729
logotron/bot.py
(13 . 6)(13 . 11)
46
47 ##############################################################################
48
49 # Version. If changing this program, always set this to same # as in MANIFEST
50 Ver = 596907
51
52 ##############################################################################
53
54 cfg = ConfigParser.ConfigParser()
55
56 ##############################################################################
(211 . 6)(216 . 9)
58 if act:
59 action = True
60 text = act.group(1)
61 # Remove turd if present:
62 if text[-1:] == '\x01':
63 text = text[:-1]
64 # This line is edible, process it.
65 eat_logline(user, chan, text, action)
66
(312 . 6)(320 . 15)
68
69 ##############################################################################
70
71 # Get perma-URL corresponding to given log line
72 def line_url(l):
73 return "{0}log/{1}/{2}#{3}".format(Base_URL,
74 l['chan'],
75 l['t'].strftime(Date_Short_Format),
76 l['idx'])
77
78 ##############################################################################
79
80 # Commands:
81
82 def cmd_help(arg, user, chan):
(324 . 7)(341 . 68)
84 speak(chan, get_search_res(chan, arg))
85
86 def cmd_seen(arg, user, chan):
87 speak(chan, "%s: this command is not yet implemented." % user);
88 # Empty query is prohibited:
89 if arg == "":
90 speak(chan, "Required argument: USER")
91 return
92
93 # Perform query:
94 seen_line = query_db(
95 '''select t, idx, payload, chan from loglines where
96 chan=%s and speaker=%s order by t desc limit 1;''',
97 [chan, arg], one=True)
98
99 # Where output will go
100 result = ""
101
102 # If user has been seen in THE CURRENT chan:
103 if seen_line != None:
104 time_txt = seen_line['t'].strftime(Date_Long_Format)
105 time_link = "[%s][%s]" % (line_url(seen_line), time_txt)
106 seen_line = "%s last seen here on %s: %s" % (arg,
107 time_link,
108 seen_line['payload'])
109 result = seen_line
110 else:
111 # If user has never been seen in this chan:
112 result = "The user %s has never been seen in #%s." % (arg, chan)
113
114 # Speak the result into the chan where command was issued
115 speak(chan, result)
116
117 def cmd_seen_anywhere(arg, user, chan):
118 # Empty query is prohibited:
119 if arg == "":
120 speak(chan, "Required argument: USER")
121 return
122
123 # Perform query:
124 seen_line = query_db(
125 '''select t, idx, payload, chan from loglines where speaker=%s
126 order by t desc limit 1;''',
127 [arg], one=True)
128
129 # Where output will go
130 result = ""
131
132 # If user has been seen in ANY logged chan:
133 if seen_line != None:
134 time_txt = seen_line['t'].strftime(Date_Long_Format)
135 time_link = "[%s][%s]" % (line_url(seen_line), time_txt)
136 seen_line = "%s last seen in #%s on %s: %s" % (arg,
137 seen_line['chan'],
138 time_link,
139 seen_line['payload'])
140 result = seen_line
141 else:
142 # If user has never been seen at all:
143 result = "The user %s has never been seen by this logger." % arg
144
145 # Speak the result into the chan where command was issued
146 speak(chan, result)
147
148 def cmd_version(arg, user, chan):
149 speak(chan, "I am bot version %s." % Ver);
150
151 def cmd_src(arg, user, chan):
152 speak(chan, "%s: my source code can be seen at: %s" % (user, Src_URL));
(343 . 11)(421 . 13)
154 (user, uptime_txt));
155
156 Commands = {
157 "help" : cmd_help,
158 "s" : cmd_search,
159 "seen" : cmd_seen,
160 "uptime" : cmd_uptime,
161 "src" : cmd_src
162 "help" : cmd_help,
163 "s" : cmd_search,
164 "seen" : cmd_seen,
165 "seen-anywhere" : cmd_seen_anywhere,
166 "uptime" : cmd_uptime,
167 "src" : cmd_src,
168 "version" : cmd_version
169 }
170
171 ##############################################################################
(384 . 8)(464 . 7)
173
174
175 # RE for finding log refs
176 logref_re = re.compile(Base_URL + """log\/([^/]+)/([^/]+)#(\d+)""")
177
178 logref_re = re.compile(Base_URL + """log\/([^/]+)/[^/]+#(\d+)""")
179
180 # All valid received lines end up here
181 def eat_logline(user, chan, text, action):
(422 . 7)(501 . 7)
183 else:
184 # Finally, see if contains log refs:
185 for ref in re.findall(logref_re, text):
186 ref_chan, ref_date, ref_idx = ref
187 ref_chan, ref_idx = ref
188 # Find this line in DB:
189 ref_line = query_db(
190 '''select t, speaker, payload from loglines
(430 . 10)(509 . 20)
192 [ref_chan, ref_idx], one=True)
193 # If retrieved line is valid, echo it:
194 if ref_line != None:
195 time_txt = ref_line['t'].strftime(Date_Long_Format)
196 my_line = "Logged on %s %s: %s" % (time_txt,
197 ref_line['speaker'],
198 ref_line['payload'])
199 # If referred line was spoken in THIS chan:
200 if ref_chan == chan:
201 time_txt = ref_line['t'].strftime(Date_Long_Format)
202 my_line = "Logged on %s %s: %s" % (time_txt,
203 ref_line['speaker'],
204 ref_line['payload'])
205 else:
206 # If this is a cross-chan echo:
207 time_txt = ref_line['t'].strftime(Date_Short_Format)
208 my_line = "(%s) %s %s: %s" % (ref_chan,
209 time_txt,
210 ref_line['speaker'],
211 ref_line['payload'])
212
213 # Speak the line echo into the chan where ref was seen
214 speak(chan, my_line)
215
- 932DB323BE19AE3D24ECEC90B63D8E0E551EDDFE2278233CFB73E66E89CF36108768D3FB8A0E5BB330D25BA31B0634F7805ADF2BE3E0ABE2D18E6A546179C6F9
+ E67F9263580FCE464D48E985CC229C279A89C2F79296DEF56631EB295DA2B4604EBDC681914C1217D139B68873F721CD5DF0AF1A82F6F199E16A87F1DBBBEDB9
logotron/reader.py
(15 . 6)(15 . 7)
220 import os
221 import threading
222 import re
223 import shlex
224 from datetime import datetime
225 from urlparse import urljoin
226 from flask import Flask, request, session, url_for, redirect, Response, \
(276 . 16)(277 . 26)
228 if ss <= l['idx'] <= se:
229 dclass = "highlight"
230
231 speaker = l['speaker']
232 separator = ":"
233
234 # If 'action', annotate:
235 if l['self']:
236 separator = ""
237 payload = "<i>" + payload + "</i>"
238 speaker = "<i>" + speaker + "</i>"
239
240 # HTMLize the given line :
241 s = ("<div id='{0}' class='{6}{5}'>"
242 "<a class='nick' title='{2}'"
243 " href=\"{3}\">{1}</a>: {4}</div>").format(l['idx'],
244 l['speaker'],
245 l['t'],
246 line_url(l),
247 payload,
248 bot,
249 dclass)
250 " href=\"{3}\">{1}</a>{5} {4}</div>").format(l['idx'],
251 speaker,
252 l['t'],
253 line_url(l),
254 payload,
255 bot,
256 dclass,
257 separator)
258 return s
259
260 # Make above callable from inside htm templater:
(436 . 6)(447 . 49)
262 return Response(res, mimetype='text/plain')
263
264
265 # "Tape" is a raw log containing entried from ALL logged chans:
266 @app.route('/tape')
267 def tape():
268 res = ""
269
270 # Get start and end indices:
271 idx_start = request.args.get('istart', default = 0, type = int)
272 idx_end = request.args.get('iend', default = 0, type = int)
273
274 # Malformed bounds?
275 if idx_start > idx_end:
276 return Response("EGGOG: Start must precede End!",
277 mimetype='text/plain')
278
279 # Demanded too many in one burst ?
280 if (idx_end - idx_start) > Max_Raw_Ln :
281 return Response("EGGOG: May request Max. of %s Lines !" % Max_Raw_Ln,
282 mimetype='text/plain')
283
284 # Get the loglines from DB
285 lines = query_db(
286 '''select * from loglines where
287 idx between %s and %s order by idx asc;''',
288 [idx_start, idx_end], one=False)
289
290 # Retrieve raw lines in Tape format:
291 for l in lines:
292 action = ""
293 speaker = "%s;" % l['speaker']
294 if l['self']:
295 action = "*;"
296 speaker = "%s " % l['speaker']
297 res += "%s;%s;%s;%s%s%s\n" % (l['chan'],
298 l['idx'],
299 l['t'].strftime('%s'),
300 action,
301 speaker,
302 l['payload'])
303
304 # Return plain text:
305 return Response(res, mimetype='text/plain')
306
307
308 Name_Chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-"
309
310 def sanitize_speaker(s):
(464 . 7)(518 . 7)
312 # Forbid query that is too short:
313 if len(query) >= Min_Query_Length:
314 # Get the search tokens to use:
315 tokens = query.split()
316 tokens = shlex.split(query)
317 tokens_standard = []
318 from_users = []
319
- 8A0C101964AE3AE0CE1687E8A6DA575C9DE35990DD0BCA507B58539DD01AF67D6E3F775F8F00CCC9EA40053B80F63815FF02E12E6A7E69A0B832949C3B8F50AD
+ 96EC2C4262FDC5A0707910CC69CCF6C522E6D4B7C0597B61672AFCFE1F17BCABE94629C97517328D1F02BC8BB8B2F96BB69D1F39027F55A671B0B290E83C6248
logotron/templates/layout.html
(78 . 11)(78 . 19)
324 .annotations a {
325 text-decoration: none;
326 }
327
328 #navbar {
329
330 .navbarblock {
331 margin-bottom: 1em;
332 }
333
334
335 .navbar {
336 float:left;
337 }
338
339 .jump {
340 float:right;
341 }
342
343 .highlight {
344 background: yellow !important;;
345 padding: 1px;
(93 . 6)(101 . 8)
347
348 <body>
349
350 <a name="head">
351
352 <p>
353 <table align="center">
354 <tr>
(137 . 6)(147 . 9)
356 <div align="center">
357 <a href="/rnd/{{ chan }}">Random({{ chan }})</a> | <a href="{{ url_for('static', filename='log_db.gz') }}">Download daily DB snapshot</a> | <a href="http://www.loper-os.org/?p=3452">Get Source Code</a>
358 </div>
359
360 <a name="tail">
361
362 </body>
363
364 </html>
- 52D528C55A54D0077907DDAE6D862D9B3E9C4AFB9D787874A8844DE4C3231B8C8D714DC2BEF369004EFBEF7CBDBA4B81EC1081F71A1EA48F5598B5780FACEF6A
+ 2A1AF43AB7AA90D58C85B05D4BADF528C9D6AF150C470629AE5394DDC577CAE27FCF42D5527659DF61A73E422AF5BA67AC0AA55AC4022091455E61CF92CE3AF8
logotron/templates/log.html
(6 . 7)(6 . 11)
369
370 {% block body %}
371
372 <div id='navbar'>{{ generate_navbar(date, tail, chan) | safe }}</div>
373 <div id="navbarblock">
374 <p class='navbar'>{{ generate_navbar(date, tail, chan) | safe }}</p>
375 <p class='jump'><a href="#tail">↓</a></p>
376 </div>
377 <div style="clear: both;"></div>
378
379 <div class='loglines'>
380 {% for l in loglines %}
(14 . 6)(18 . 10)
382 {% endfor %}
383 </div>
384
385 <div id='navbar'>{{ generate_navbar(date, tail, chan) | safe }}</div>
386 <div id="navbarblock">
387 <p class='navbar'>{{ generate_navbar(date, tail, chan) | safe }}</p>
388 <p class='jump'><a href="#head">↑</a></p>
389 </div>
390 <div style="clear: both;"></div>
391
392 {% endblock %}