直接open source 我自己的py

description: 触发性ui交互、

===挂屏小窗脚本===

1.shift+shift键显示/隐藏

2.shift+enter退出程序

3.5分钟更新记录 并触发<后置清晰脚本>

4.ctrl+左右键 可以切换前后记录

===规则===

当处在非最新信息的时候,输入新增文字,此时过去文字+新增文字 组成的新段落 后续会视为最新的一版存入记录.txt!!!

===配套清洗脚本===

1.针对txt中的数据记录 去重相似度超过90%的数据

2.覆盖回原文件

python 复制代码
import sys
import json
import time
import subprocess
from datetime import datetime
from pathlib import Path
from threading import Thread, Event
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import keyboard
from flask import Flask, request, jsonify

# ====================== 配置 ======================
SCRIPT_DIR = Path(sys.argv[0]).parent
SAVE_FILE = SCRIPT_DIR / "记录.txt"
INTERVAL_MIN = 5
PORT = 16888
HOTKEY = "shift+shift"
CLEAN_SCRIPT = SCRIPT_DIR / "后置清晰.py"

# ====================== 全局变量 ======================
last_saved_content = None
records = []
current_index = -1
last_refresh_time = 0
REFRESH_COOLDOWN = 15
is_editing_based_on_history = False

# ====================== 悬浮窗主窗口 ======================
class FloatWindow(QMainWindow):
    updateTextSignal = pyqtSignal(str)
    updateLabelSignal = pyqtSignal(str)

    def __init__(self):
        super().__init__()
        self.setWindowTitle("监控悬浮窗")
        self.setFixedSize(800, 560)
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool)
        self.setAttribute(Qt.WA_TranslucentBackground)

        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)
        self.main_layout = QVBoxLayout(self.central_widget)
        self.main_layout.setContentsMargins(0,0,0,0)
        self.main_layout.setSpacing(0)

        self.title_bar = QWidget()
        self.title_bar.setFixedHeight(40)
        self.title_bar.setCursor(Qt.SizeAllCursor)
        self.main_layout.addWidget(self.title_bar)

        self.content_widget = QWidget()
        self.content_widget.setStyleSheet("background-color:#2c2c2c;border-radius:10px;")
        self.content_layout = QVBoxLayout(self.content_widget)
        self.main_layout.addWidget(self.content_widget)

        self.text_edit = QTextEdit()
        self.text_edit.setPlaceholderText("这里是要被抓取的内容")
        font = self.text_edit.font()
        new_size = int(font.pointSize() * 1.3)
        font.setPointSize(new_size)
        self.text_edit.setFont(font)

        self.page_label = QLabel("📄 实时内容")
        self.page_label.setStyleSheet("color:#aaa;padding:5px;")
        self.content_layout.addWidget(self.page_label)
        self.content_layout.addWidget(self.text_edit)

        self.text_edit.setStyleSheet("""
            QTextEdit {color:white;background-color:#3a3c3c;border-radius:5px;padding:5px;}
        """)

        self.dragging = False
        self.offset = QPoint()

        self.text_edit.textChanged.connect(on_text_edited)
        self.updateTextSignal.connect(self.safe_set_text)

        # Ctrl+S 快捷键
        self.save_shortcut = QShortcut(QKeySequence("Ctrl+S"), self)
        self.save_shortcut.activated.connect(self.manual_save)

    # ========== 核心:强制保存(一定写入) ==========
    def manual_save(self):
        try:
            content = self.get_content()
            if not content:
                print("❌ 内容为空,不保存")
                return

            # 强制保存,无视重复,直接追加写入
            now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            data = {
                "timestamp": int(time.time()),
                "time_str": now,
                "content": content
            }
            with open(SAVE_FILE, "a", encoding="utf-8") as f:
                f.write(json.dumps(data, ensure_ascii=False) + "\n")

            global last_saved_content
            last_saved_content = content
            load_all_records()
            print("✅ Ctrl+S 已强制保存新记录!")
        except Exception as e:
            print("保存失败:", e)

    # ========== 【修复】全窗口可拖动 ==========
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.dragging = True
            self.offset = event.globalPos() - self.pos()
            event.accept()

    def mouseMoveEvent(self, event):
        if self.dragging and event.buttons() == Qt.LeftButton:
            self.move(event.globalPos() - self.offset)
            event.accept()

    def mouseReleaseEvent(self, event):
        self.dragging = False
        event.accept()

    def safe_set_text(self, text):
        self.text_edit.blockSignals(True)
        self.text_edit.setPlainText(text)
        self.text_edit.blockSignals(False)

    def get_content(self):
        return self.text_edit.toPlainText().strip()

# ====================== 辅助函数 ======================
def on_text_edited():
    global is_editing_based_on_history, current_index
    if len(records) == 0:
        return
    if current_index != len(records) - 1:
        is_editing_based_on_history = True

def load_all_records():
    global records, current_index
    if not SAVE_FILE.exists():
        records = []
        current_index = -1
        return []
    try:
        with open(SAVE_FILE, "r", encoding="utf-8") as f:
            lines = [line.strip() for line in f if line.strip()]
        temp = []
        for line in lines:
            try:
                temp.append(json.loads(line))
            except:
                continue
        temp.sort(key=lambda x: x.get("timestamp", 0))
        records = temp
        current_index = len(records) - 1
    except:
        records = []
        current_index = -1

def show_record(index):
    if not records:
        window.updateTextSignal.emit("暂无记录")
        return
    if 0 <= index < len(records):
        txt = records[index]["content"]
        window.updateTextSignal.emit(txt)
        global current_index
        current_index = index

def safe_refresh_records():
    global last_refresh_time
    if is_editing_based_on_history:
        return
    now = time.time()
    if now - last_refresh_time >= REFRESH_COOLDOWN:
        load_all_records()
        last_refresh_time = now

# ====================== 方向键 ======================
def arrow_key_listener():
    while True:
        try:
            if keyboard.is_pressed("ctrl+left"):
                safe_refresh_records()
                if current_index > 0:
                    show_record(current_index - 1)
                time.sleep(0.3)

            if keyboard.is_pressed("ctrl+right"):
                safe_refresh_records()
                if current_index < len(records) - 1:
                    show_record(current_index + 1)
                else:
                    show_record(len(records)-1)
                time.sleep(0.3)
        except:
            pass
        time.sleep(0.05)

# ====================== 保存功能 ======================
def run_clean_script():
    if not CLEAN_SCRIPT.exists():
        return
    try:
        si = subprocess.STARTUPINFO()
        si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        subprocess.Popen([sys.executable, str(CLEAN_SCRIPT)], cwd=str(SCRIPT_DIR),
                         startupinfo=si, creationflags=subprocess.CREATE_NO_WINDOW)
    except:
        return

def save_content(content, force=False):
    global last_saved_content, is_editing_based_on_history
    if not content:
        return
    if not force and (content == last_saved_content):
        return

    now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    data = {"timestamp": int(time.time()), "time_str": now, "content": content}
    try:
        with open(SAVE_FILE, "a", encoding="utf-8") as f:
            f.write(json.dumps(data, ensure_ascii=False) + "\n")
        last_saved_content = content
        is_editing_based_on_history = False
        load_all_records()
        run_clean_script()
    except:
        return

# ====================== 快捷键 ======================
def timer_task(stop_event):
    while not stop_event.is_set():
        time.sleep(INTERVAL_MIN * 60)
        save_content(window.get_content())

def hotkey_listener():
    while True:
        keyboard.wait(HOTKEY)
        window.setVisible(not window.isVisible())
        time.sleep(0.3)

def exit_hotkey_listener(stop_event, app):
    while True:
        keyboard.wait("shift+enter")
        try:
            current_content = window.get_content()
            save_content(current_content, force=True)
            time.sleep(0.1)
        except:
            pass
        stop_event.set()
        app.quit()
        sys.exit(0)

# ====================== API ======================
app = Flask(__name__)
window = None

@app.route("/status")
def status():
    return jsonify({"visible": window.isVisible(), "last": window.get_content()})

@app.route("/capture", methods=["POST"])
def capture():
    save_content(window.get_content())
    return jsonify({"code":0})

@app.route("/toggle", methods=["POST"])
def toggle():
    window.setVisible(not window.isVisible())
    return jsonify({"code":0})

def run_api():
    app.run(host="0.0.0.0", port=PORT, debug=False, use_reloader=False)

# ====================== 主程序 ======================
def main():
    global window
    app_qt = QApplication(sys.argv)
    window = FloatWindow()
    window.show()
    load_all_records()

    try:
        with open(SAVE_FILE, "r", encoding="utf-8") as f:
            lines = [l.strip() for l in f if l.strip()]
        if lines:
            last = json.loads(lines[-1])["content"]
            window.updateTextSignal.emit(last)
            global last_saved_content
            last_saved_content = last
    except:
        pass

    Thread(target=hotkey_listener, daemon=True).start()
    Thread(target=arrow_key_listener, daemon=True).start()
    stop_event = Event()
    Thread(target=timer_task, args=(stop_event,), daemon=True).start()
    Thread(target=run_api, daemon=True).start()
    Thread(target=exit_hotkey_listener, args=(stop_event, app_qt), daemon=True).start()

    app_qt.exec_()
    stop_event.set()

if __name__ == "__main__":
    main()

part2:======================

python 复制代码
import json
from difflib import SequenceMatcher

SIMILARITY_THRESHOLD = 0.9

def similar(a, b):
    return SequenceMatcher(None, a, b).ratio()

with open("记录.txt", "r", encoding="utf-8") as f:
    lines = [line.rstrip("\n") for line in f if line.strip()]

items = []
for line in lines:
    try:
        d = json.loads(line)
        items.append((line, d.get("content", "")))
    except:
        items.append((line, ""))

unique = []
contents = []

for raw, cnt in items:
    dup = False
    for c in contents:
        if similar(cnt, c) >= SIMILARITY_THRESHOLD:
            dup = True
            break
    if not dup:
        unique.append(raw)
        contents.append(cnt)

with open("记录.txt", "w", encoding="utf-8") as f:
    f.write("\n".join(unique) + "\n")

print(f"去重完成!原条目:{len(items)},保留:{len(unique)},已覆盖原文件")
相关推荐
AI技术增长1 小时前
Pytorch图像去噪实战(一):从0复现DnCNN并解决训练不收敛问题(附完整工程+踩坑总结)
人工智能·pytorch·python
a7963lin1 小时前
c#如何实现幂等消费_c#幂等消费的几种常见用法
jvm·数据库·python
kexnjdcncnxjs1 小时前
Redis怎样实现Session的分布式共享
jvm·数据库·python
wx_xsooop1 小时前
iOS 审核 上架 被拒 4.3 【深度进阶】
python·编程·技术
tjc199010051 小时前
mysql如何防止SQL注入攻击_mysql参数化查询与转义
jvm·数据库·python
盐烟1 小时前
xpath翻页爬取
python
m0_741173332 小时前
MySQL导入大SQL文件报错怎么办_拆分文件与优化系统参数
jvm·数据库·python
矢志航天的阿洪2 小时前
手动安装Gurobi并配置gurobipy到Python环境(Windows/Conda)
windows·python·conda
IT空门:门主2 小时前
Python 数据类型学习笔记
python·学习