minecraft-heatmap/mclog2mysql/main.py

62 lines
2.0 KiB
Python

#!/usr/bin/env nix-shell
#!nix-shell -i python3 -p "python3.withPackages(ps: with ps; [ tqdm ])"
from tqdm import tqdm
from pprint import pprint
from pathlib import Path
from datetime import datetime
import gzip
# Currently not mysql lol
import sqlite3
def parse_login_logout_events_from_file(path: Path):
date = path.name[:10]
result = []
with gzip.open(path, 'r') as file:
for line in file:
if b'joined the game' in line or b'left the game' in line:
split = line.decode().split()
time = datetime.fromisoformat(f"{date} {split[0][1:9]}")
name = split[3]
state = split[4]
result.append((time, name, state))
return result
def conjoin_sessions(event_log):
result = []
login_session_table = dict()
for time, name, state in event_log:
if state == 'joined':
login_session_table[name] = time
elif name in login_session_table:
result.append((name, time, (time - login_session_table[name]).total_seconds()))
del login_session_table[name]
else:
print(f"warn: loose session found for {name} at {time}")
return result
def insert_sessions_into_db(session_log):
con = sqlite3.connect("test.db")
cur = con.cursor()
cur.execute("DROP TABLE IF EXISTS minecraft_login_sessions")
cur.execute("""
CREATE TABLE minecraft_login_sessions(
username TEXT NOT NULL,
start DATETIME,
duration INTEGER
)
""")
cur.executemany("INSERT INTO minecraft_login_sessions(username, start, duration) VALUES(?, ?, ?)", session_log)
con.commit()
if __name__ == "__main__":
event_log = []
files = list(Path(__file__).parent.glob(r"*.log.gz"))
for file in (pbar:=tqdm(files)):
pbar.set_postfix_str(file)
event_log += parse_login_logout_events_from_file(file)
session_log = conjoin_sessions(event_log)
insert_sessions_into_db(session_log)