Created
January 15, 2015 02:31
-
-
Save foota/6365c35001bc7d411fea to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
import sys | |
import os | |
import socket | |
import string | |
import datetime | |
import time | |
import re | |
import sqlite3 | |
import logging | |
VERSION = "0.11" | |
REVISION = "b" | |
VER_DATE = "20150113" | |
SERVER = "irc.your_domain.com" | |
PORT = 6667 | |
NICKNAME = "techbot" | |
CHANNEL = "#tech" | |
logging.basicConfig(level=logging.INFO) | |
SQLITE_DB = "irc_users.dat" | |
con = sqlite3.connect(SQLITE_DB, check_same_thread=True) | |
cur = con.cursor() | |
cur.execute(""" | |
CREATE TABLE IF NOT EXISTS userdata | |
(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, username TEXT, join_time INTEGER, quit_time INTEGER, duration INTEGER) | |
""") | |
INSERT_DB = "INSERT INTO userdata VALUES(NULL,?,?,?,?)" | |
IRC = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
def irc_conn(): | |
IRC.connect((SERVER, PORT)) | |
def send_data(command): | |
IRC.send(command + "\n") | |
def join(channel): | |
send_data("JOIN %s" % channel) | |
def login(nickname, username="techbot", password=None, realname="techbot", hostname="irc.your_domain.com", servername="irc.your_domain.com"): | |
send_data("USER %s %s %s %s" % (username, hostname, servername, realname)) | |
send_data("NICK " + nickname) | |
def main(args): | |
irc_conn() | |
login(NICKNAME) | |
join(CHANNEL) | |
log_date = datetime.date.today().isoformat() | |
logf = file("irc_%s.log" % log_date, "a+") | |
logm = [l for l in logf] | |
status = "" | |
is_finished = False | |
buffer = "" | |
while (1): | |
today = datetime.date.today().isoformat() | |
if log_date != today: | |
log_date = today | |
logf.close() | |
logf = file("irc_%s.log" % log_date, "a+") | |
logm = [] | |
buffer += IRC.recv(4096) | |
if not string.split(buffer): continue | |
lines = string.split(buffer, "\n") | |
buffer = lines[-1] | |
for line in lines[:-1]: | |
line += "\n" | |
sys.stdout.write(line) | |
sys.stdout.flush() | |
msg = string.split(line) | |
if msg[0] == "PING": | |
send_data("PONG %s" % msg[1]) | |
if msg[1] == "JOIN": | |
nickname = msg[0][1:string.find(msg[0], "!")] | |
cur.execute("SELECT quit_time FROM userdata WHERE username='%s'" % nickname) | |
s = cur.fetchone() | |
now = int(time.mktime(datetime.datetime.now().timetuple())) | |
if s: | |
cur.execute("UPDATE userdata SET join_time=%d WHERE username='%s'" % (now, nickname)) | |
else: | |
cur.execute(INSERT_DB, (nickname, now, None, 0)) | |
con.commit() | |
send_data(":%s LIST %s\n" % (NICKNAME, CHANNEL)) | |
status = "JOIN" | |
if msg[1] in ("QUIT", "PART"): | |
nickname = msg[0][1:string.find(msg[0], "!")] | |
cur.execute("SELECT join_time FROM userdata WHERE username='%s'" % nickname) | |
s = cur.fetchone() | |
now = int(time.mktime(datetime.datetime.now().timetuple())) | |
if s: | |
duration = 0 | |
if s[0]: duration = now - int(s[0]) | |
cur.execute("SELECT duration FROM userdata WHERE username='%s'" % nickname) | |
s = cur.fetchone() | |
if s and s[0]: duration += int(s[0]) | |
cur.execute("UPDATE userdata SET quit_time=%d, duration=%d WHERE username='%s'" % (now, duration, nickname)) | |
else: | |
cur.execute(INSERT_DB, (nickname, None, now, 0)) | |
con.commit() | |
send_data(":%s LIST %s\n" % (NICKNAME, CHANNEL)) | |
status = "QUIT" | |
if msg[1] == "322": | |
if msg[3] == CHANNEL and msg[4] == "2": | |
if status == "JOIN": | |
send_data(":%s PRIVMSG %s :%s\n" % (NICKNAME, CHANNEL, "一番乗りですね。")) | |
if status == "QUIT": | |
send_data(":%s PRIVMSG %s :%s\n" % (NICKNAME, CHANNEL, "お疲れさまです。最後になりました。")) | |
if msg[1] == "PRIVMSG" or msg[1] == "NOTICE": | |
if msg[2] not in (CHANNEL, NICKNAME): continue | |
if msg[1] == "PRIVMSG": | |
nickname = msg[0][1:string.find(msg[0], "!")] | |
message = " ".join(msg[3:]) | |
m = re.search(r"techlog\:(.*)", message) | |
if m: | |
cur.execute("SELECT quit_time FROM userdata WHERE username='%s'" % nickname) | |
s = cur.fetchone() | |
logmm = logm[:] | |
if s and s[0]: | |
prevlogs = [] | |
quit_time = datetime.datetime.fromtimestamp(int(s[0])) | |
quit_date = quit_time.date() | |
while quit_date < datetime.date.today(): | |
logff = file("irc_%s.log" % quit_date.isoformat(), "r") | |
prevlogs.extend([l for l in logff]) | |
quit_date += datetime.timedelta(1) | |
logff.close() | |
prevlogs.extend(logm[:]) | |
logmm = [] | |
for l in prevlogs: | |
xs = l.split("#") | |
tm = datetime.datetime.strptime(xs[0], "%Y-%m-%dT%H:%M:%S.%f") | |
if tm > quit_time: | |
logmm.append(l) | |
for l in logmm: | |
xs = l.split("#") | |
tm = datetime.datetime.strptime(xs[0], "%Y-%m-%dT%H:%M:%S.%f") | |
msg = "#".join(xs[1:]) | |
send_data(":%s PRIVMSG %s :%s %s\n" % (NICKNAME, nickname, tm.time().isoformat().split(".")[0], msg)) | |
m = re.search(r"techquit\:(.*)", message) | |
if m: | |
is_finished = True | |
break | |
m = re.search(r"techtime\:(.*)", message) | |
if m: | |
cur.execute("SELECT duration FROM userdata WHERE username='%s'" % nickname) | |
s = cur.fetchone() | |
duration = datetime.timedelta(seconds=0) | |
if s and s[0]: | |
duration = datetime.timedelta(seconds=int(s[0])) | |
cur.execute("SELECT join_time FROM userdata WHERE username='%s'" % nickname) | |
s = cur.fetchone() | |
if s and s[0]: | |
duration += datetime.timedelta(seconds=int(time.mktime(datetime.datetime.now().timetuple())) - int(s[0])) | |
seconds = duration.seconds | |
minutes, seconds = seconds / 60, seconds % 60 | |
hours, minutes = minutes / 60, minutes % 60 | |
send_data(":%s PRIVMSG %s :あなたは、%d日%d時間%d分%d秒、%s に滞在しました。\n" % (NICKNAME, nickname, duration.days, hours, minutes, seconds, CHANNEL)) | |
m = re.search(r"techtimeall\:(.*)", message) | |
if m: | |
cur.execute("SELECT duration, username FROM userdata") | |
for s in cur: | |
if s and s[1] and s[1] == NICKNAME: | |
continue | |
duration = datetime.timedelta(seconds=0) | |
if s and s[0]: | |
duration = datetime.timedelta(seconds=int(s[0])) | |
seconds = duration.seconds | |
minutes, seconds = seconds / 60, seconds % 60 | |
hours, minutes = minutes / 60, minutes % 60 | |
send_data(":%s PRIVMSG %s :%s は、%d日%d時間%d分%d秒、%s に滞在しました。\n" % (NICKNAME, nickname, str(s[1]), duration.days, hours, minutes, seconds, CHANNEL)) | |
m = re.search(r"techbotkawaii\:(.*)", message) | |
if m: | |
send_data(":%s PRIVMSG %s :%s\n" % (NICKNAME, nickname, "ありがと!")) | |
if msg[2] != CHANNEL: continue | |
nickname = msg[0][1:string.find(msg[0], "!")] | |
message = " ".join(msg[3:]) | |
message = "%s#(%s) %s\n" % (datetime.datetime.now().isoformat(), string.lstrip(nickname, ":"), string.lstrip(message, ":")) | |
logf.write(message) | |
logf.flush() | |
logm.append(message) | |
if is_finished: | |
break | |
logf.close() | |
if __name__ == "__main__": main(sys.argv) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment