- 80D24124B12055C919F68583A83445477D13680DB62960B9AC57A6D7CA066F52973E9FC1BC3F80ECF6B541D0784CFBFA10195792F2A9D786C57143720584F88A
+ D33D6B379DC88808FD72E9579D23818B7A2611D24F48E07ED4EBA2DCDC97E228D7F45C34F939FC282146ED3E89F320D709CF023711C9DBB0394DFD39B36DCF4C
logotron/bot.py
(14 . 7)(14 . 7)
250 ##############################################################################
251
252 # Version. If changing this program, always set this to same # as in MANIFEST
253 Ver = 597858
254 Ver = 684804
255
256 ##############################################################################
257
(74 . 6)(74 . 7)
259 DB_DEBUG = cfg.get("db", "db_debug")
260 # Logism:
261 Base_URL = cfg.get("logotron", "base_url")
262 App_Root = cfg.get("logotron", "app_root")
263 Era = int(cfg.get("logotron", "era"))
264 NewChan_Idx = int(cfg.get("logotron", "newchan_idx"))
265 Src_URL = cfg.get("logotron", "src_url")
(142 . 7)(143 . 7)
267 def init_socket():
268 global sock
269 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
270
271
272 # Disable Nagle's algorithm for transmit operations
273 sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
274 # Disable Nagle's algorithm for receive operation, Linux-only
(150 . 7)(151 . 7)
276 sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 1)
277 except Exception as e:
278 logging.warning(e)
279
280
281 connected = False
282
283 def deinit_socket():
(250 . 32)(251 . 32)
285 global time_last_conn
286 global time_last_recv
287 global sock
288
289
290 # Initialize a socket
291 init_socket()
292
293
294 # Connect to one among the specified servers, in given priority :
295 while not connected:
296 connected = connect_any(Servers, Port)
297
298 # Save time of last successful connect
299 time_last_conn = datetime.now()
300
301
302 # Auth to server
303 send("NICK %s\r\n" % Nick)
304 send("USER %s %s %s :%s\r\n" % (Nick, Nick, Nick, Nick))
305
306
307 # If this is a production bot, rather than test, there will be a PW:
308 if Pass != "":
309 send("NICKSERV IDENTIFY %s %s\r\n" % (Nick, Pass))
310
311
312 time.sleep(Join_Delay) # wait to join until fleanode eats auth
313
314
315 # Join selected channels
316 for chan in Channels:
317 logging.info("Joining channel '%s'..." % chan)
318 send("JOIN #%s\r\n" % chan)
319
320
321 while connected:
322 try:
323 data = sock.recv(Buf_Size)
(355 . 7)(356 . 8)
325
326 # Get perma-URL corresponding to given log line
327 def line_url(l):
328 return "{0}log/{1}/{2}#{3}".format(Base_URL,
329 return "{0}{1}{2}/{3}#{4}".format(Base_URL,
330 App_Root,
331 l['chan'],
332 l['t'].strftime(Date_Short_Format),
333 l['idx'])
(378 . 7)(380 . 7)
335 if arg == "":
336 speak(chan, "Required argument: USER")
337 return
338
339
340 # Perform query:
341 seen_line = query_db(
342 '''select t, idx, payload, chan from loglines where
(387 . 7)(389 . 7)
344
345 # Where output will go
346 result = ""
347
348
349 # If user has been seen in THE CURRENT chan:
350 if seen_line != None:
351 time_txt = seen_line['t'].strftime(Date_Long_Format)
(399 . 7)(401 . 7)
353 else:
354 # If user has never been seen in this chan:
355 result = "The user %s has never been seen in #%s." % (arg, chan)
356
357
358 # Speak the result into the chan where command was issued
359 speak(chan, result)
360
(408 . 7)(410 . 7)
362 if arg == "":
363 speak(chan, "Required argument: USER")
364 return
365
366
367 # Perform query:
368 seen_line = query_db(
369 '''select t, idx, payload, chan from loglines where speaker=%s
(417 . 7)(419 . 7)
371
372 # Where output will go
373 result = ""
374
375
376 # If user has been seen in ANY logged chan:
377 if seen_line != None:
378 time_txt = seen_line['t'].strftime(Date_Long_Format)
(474 . 20)(476 . 20)
380 '''select idx from loglines where chan=%s
381 and idx = (select max(idx) from loglines where chan=%s) ;''',
382 [chan, chan], one=True)
383
384
385 # Was this chan unseen previously?
386 if last_idx == None:
387 cur_idx = NewChan_Idx # Then use the config'd start index
388 else:
389 cur_idx = last_idx['idx'] + 1 # Otherwise, get the next idx
390
391
392 logging.debug("Adding log line with index: %s" % cur_idx)
393
394 # Set up the insert
395 exec_db('''insert into loglines (idx, t, chan, era,
396 speaker, self, payload) values (%s, %s, %s, %s, %s, %s, %s) ; ''',
397 [cur_idx, time, chan, Era, speaker, action, payload])
398
399
400 # Fire
401 commit_db()
402 except Exception as e:
(497 . 7)(499 . 10)
404
405
406 # RE for finding log refs
407 logref_re = re.compile(Base_URL + """log\/([^/]+)/[^/]+#(\d+)""")
408 if App_Root == '/':
409 logref_re = re.compile(Base_URL + """([^/]+)/[^/]+#(\d+)""")
410 else:
411 logref_re = re.compile(Base_URL + App_Root.strip('/') + """\/([^/]+)/[^/]+#(\d+)""")
412
413 # All valid received lines end up here
414 def eat_logline(user, chan, text, action):
(506 . 10)(511 . 10)
416 logging.warning(
417 "Received martian : '%s' : '%s'" % (chan, text))
418 return
419
420
421 # First, add the line to the log:
422 save_line(datetime.now(), chan, user, action, text)
423
424
425 # Then, see if the line was a command for this bot:
426 if text.startswith(Prefix):
427 cmd = text.partition(Prefix)[2].strip()
(555 . 7)(560 . 7)
429 time_txt,
430 ref_line['speaker'],
431 ref_line['payload'])
432
433
434 # Speak the line echo into the chan where ref was seen
435 speak(chan, my_line)
436