139 lines
4.5 KiB
Python
139 lines
4.5 KiB
Python
import os
|
|
import time
|
|
import configparser
|
|
from pynput import mouse
|
|
import win32clipboard
|
|
import win32con
|
|
from html2text import html2text
|
|
import keyboard
|
|
import threading
|
|
import sys
|
|
import logging
|
|
|
|
class TextCaptureApp:
|
|
def __init__(self):
|
|
self.load_config()
|
|
self.running = True
|
|
self.last_right_click_time = 0
|
|
self.setup_logging()
|
|
|
|
def load_config(self):
|
|
config = configparser.ConfigParser()
|
|
config.read('config.ini')
|
|
self.double_click_threshold = config.getfloat('Settings', 'double_click_threshold', fallback=0.3)
|
|
self.save_location = config.get('Settings', 'save_location', fallback=os.path.join(os.path.expanduser('~'), 'Desktop'))
|
|
self.copy_delay = config.getfloat('Settings', 'copy_delay', fallback=0.1)
|
|
|
|
def setup_logging(self):
|
|
logging.basicConfig(
|
|
filename='text_capture.log',
|
|
level=logging.INFO,
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
|
)
|
|
self.logger = logging.getLogger(__name__)
|
|
|
|
def save_to_markdown(self, content):
|
|
try:
|
|
timestamp = time.strftime("%Y%m%d_%H%M%S")
|
|
file_path = os.path.join(self.save_location, f'captured_text_{timestamp}.md')
|
|
|
|
with open(file_path, 'w', encoding='utf-8') as f:
|
|
f.write(content)
|
|
self.logger.info(f"Content saved to: {file_path}")
|
|
except Exception as e:
|
|
self.logger.error(f"Error saving file: {e}")
|
|
|
|
def get_clipboard_content(self):
|
|
try:
|
|
win32clipboard.OpenClipboard()
|
|
|
|
try:
|
|
content = win32clipboard.GetClipboardData(win32con.CF_HTML)
|
|
self.logger.info("Clipboard HTML content captured")
|
|
return html2text(content)
|
|
except:
|
|
pass
|
|
|
|
try:
|
|
content = win32clipboard.GetClipboardData(win32con.CF_TEXT)
|
|
self.logger.info("Clipboard TEXT content captured")
|
|
return content.decode('gbk')
|
|
except:
|
|
pass
|
|
|
|
try:
|
|
content = win32clipboard.GetClipboardData(win32con.CF_UNICODETEXT)
|
|
self.logger.info("Clipboard UNICODE TEXT content captured")
|
|
return content
|
|
except:
|
|
return None
|
|
|
|
except Exception as e:
|
|
self.logger.error(f"Error getting clipboard content: {e}")
|
|
return None
|
|
finally:
|
|
try:
|
|
win32clipboard.CloseClipboard()
|
|
except Exception as e:
|
|
self.logger.error(f"Error closing clipboard: {e}")
|
|
|
|
def simulate_copy(self):
|
|
keyboard.press('ctrl')
|
|
keyboard.press('c')
|
|
keyboard.release('c')
|
|
keyboard.release('ctrl')
|
|
time.sleep(self.copy_delay) # 等待复制操作完成
|
|
|
|
def on_click(self, x, y, button, pressed):
|
|
if not pressed:
|
|
return
|
|
|
|
if button == mouse.Button.right:
|
|
current_time = time.time()
|
|
if (current_time - self.last_right_click_time) < self.double_click_threshold:
|
|
self.simulate_copy()
|
|
content = self.get_clipboard_content()
|
|
if content:
|
|
self.save_to_markdown(content)
|
|
else:
|
|
self.logger.warning("No content captured from clipboard")
|
|
self.last_right_click_time = current_time
|
|
|
|
def on_keyboard_event(self, event):
|
|
# 监听Esc键退出程序
|
|
if event.name == 'esc':
|
|
self.running = False
|
|
return False
|
|
|
|
def run(self):
|
|
self.logger.info("Text Capture App started")
|
|
print("文本捕获程序已启动...")
|
|
print("使用说明:")
|
|
print("1. 选中要保存的文本")
|
|
print("2. 快速双击鼠标右键来保存选中的文本")
|
|
print("3. 按ESC键退出程序")
|
|
|
|
mouse_listener = mouse.Listener(on_click=self.on_click)
|
|
mouse_listener.start()
|
|
|
|
# 启动键盘监听
|
|
keyboard.on_press(self.on_keyboard_event)
|
|
|
|
# Wait until the running flag becomes False
|
|
while self.running:
|
|
time.sleep(0.1)
|
|
|
|
print("\n程序已退出")
|
|
mouse_listener.stop()
|
|
mouse_listener.join()
|
|
keyboard_listener.stop()
|
|
keyboard_listener.join()
|
|
self.logger.info("Text Capture App stopped")
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
app = TextCaptureApp()
|
|
app.run()
|
|
except Exception as e:
|
|
logging.error(f"程序发生错误: {e}")
|
|
input("按Enter键退出...") |