import json

import datetime
import psycopg2.extras
from psycopg2._json import Json

from pajbot.managers.redis import RedisManager


def up(cursor, bot):
    cursor.execute(
        """
    CREATE TABLE admin_log_entry(
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        type TEXT NOT NULL,
        user_id TEXT REFERENCES "user"(id) ON DELETE SET NULL,
        message TEXT NOT NULL,
        created_at TIMESTAMPTZ NOT NULL,
        data JSONB NOT NULL
    )
    """
    )
    cursor.execute("CREATE INDEX ON admin_log_entry(created_at)")

    redis = RedisManager.get()
    redis_list_raw = redis.lrange(f"{bot.streamer}:logs:admin", 0, -1)  # 0
    redis_list = [json.loads(raw_entry) for raw_entry in redis_list_raw]

    def redis_to_db_row(redis_entry):
        created_at_raw = redis_entry["created_at"]
        created_at_raw = created_at_raw.rstrip("+00:00")
        created_at = datetime.datetime.strptime(created_at_raw, "%Y-%m-%d %H:%M:%S %Z").replace(
            tzinfo=datetime.timezone.utc
        )
        return (
            redis_entry["type"],
            redis_entry["user_id"],
            redis_entry["message"],
            created_at,
            Json(redis_entry["data"]),  # for usage with the JSONB column
        )

    rows = [redis_to_db_row(redis_entry) for redis_entry in redis_list]

    psycopg2.extras.execute_values(
        cursor, "INSERT INTO admin_log_entry(type, user_id, message, created_at, data) VALUES %s", rows
    )

    # on success, delete admin logs in redis
    redis.delete(f"{bot.streamer}:logs:admin")

import json

import datetime
import psycopg2.extras
from psycopg2._json import Json

from pajbot.managers.redis import RedisManager


def up(cursor, bot):
    cursor.execute(
        """
    CREATE TABLE admin_log_entry(
        id INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
        type TEXT NOT NULL,
        user_id TEXT REFERENCES "user"(id) ON DELETE SET NULL,
        message TEXT NOT NULL,
        created_at TIMESTAMPTZ NOT NULL,
        data JSONB NOT NULL
    )
    """
    )
    cursor.execute("CREATE INDEX ON admin_log_entry(created_at)")

    def safe_get_time(time_raw):
        try:
            # Attempt #1: 2016-04-13 19:42:19 UTC
            return datetime.datetime.strptime(time_raw, "%Y-%m-%d %H:%M:%S %Z")
        except ValueError:
            pass

        try:
            # Attempt #2: 2016-04-13 19:42:19 UTC+00:00
            return datetime.datetime.strptime(time_raw, "%Y-%m-%d %H:%M:%S %Z%z")
        except ValueError:
            pass

        # Attempt 3: 2016-04-13 19:42:19.908536
        return datetime.datetime.strptime(time_raw, "%Y-%m-%d %H:%M:%S.%f")

    redis = RedisManager.get()
    redis_list_raw = redis.lrange(f"{bot.streamer}:logs:admin", 0, -1)  # 0
    redis_list = [json.loads(raw_entry) for raw_entry in redis_list_raw]

    def redis_to_db_row(redis_entry):
        created_at_raw = redis_entry["created_at"]
        created_at = safe_get_time(created_at_raw).replace(tzinfo=datetime.timezone.utc)
        return (
            redis_entry["type"],
            redis_entry["user_id"],
            redis_entry["message"],
            created_at,
            Json(redis_entry["data"]),  # for usage with the JSONB column
        )

    rows = [redis_to_db_row(redis_entry) for redis_entry in redis_list]

    psycopg2.extras.execute_values(
        cursor, "INSERT INTO admin_log_entry(type, user_id, message, created_at, data) VALUES %s", rows
    )

    # on success, delete admin logs in redis
    redis.delete(f"{bot.streamer}:logs:admin")

Add a friendlier time converter