from __future__ import annotations from pathlib import Path from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, QPlainTextEdit, QTabWidget, QListWidget, QListWidgetItem, ) from PyQt6.QtCore import pyqtSignal from workers.git_worker import GitWorker import subprocess class GitView(QWidget): refresh_needed = pyqtSignal() def __init__(self, repo_path: Path, parent=None): super().__init__(parent) self._repo_path = repo_path self._worker: GitWorker | None = None self._build_ui() def _build_ui(self): layout = QVBoxLayout(self) status_row = QHBoxLayout() self._branch_label = QLabel("Branch: โ€”") self._branch_label.setStyleSheet("color:#a855f7;font-weight:bold;") status_row.addWidget(self._branch_label) status_row.addStretch() refresh_btn = QPushButton("๐Ÿ”„ Refresh") refresh_btn.clicked.connect(self.load_status) status_row.addWidget(refresh_btn) layout.addLayout(status_row) tabs = QTabWidget() status_tab = QWidget() st_layout = QVBoxLayout(status_tab) self._status_log = QPlainTextEdit() self._status_log.setReadOnly(True) self._status_log.setStyleSheet("background:#0a0a12;color:#ccc;font-family:monospace;font-size:11px;") st_layout.addWidget(self._status_log) btns = QHBoxLayout() for label, slot in [ ("โฌ‡ Pull", self._do_pull), ("๐Ÿงช Push master", self._do_push_master), ("๐Ÿšข Push production", self._do_push_production), ]: btn = QPushButton(label) btn.clicked.connect(slot) btns.addWidget(btn) btns.addStretch() st_layout.addLayout(btns) tabs.addTab(status_tab, "Stato repo") deleted_tab = QWidget() del_layout = QVBoxLayout(deleted_tab) del_layout.addWidget(QLabel("Articoli eliminati (da git log):")) self._deleted_list = QListWidget() del_layout.addWidget(self._deleted_list) restore_btn = QPushButton("โ™ป๏ธ Ripristina selezionato") restore_btn.clicked.connect(self._do_restore) del_layout.addWidget(restore_btn) tabs.addTab(deleted_tab, "Articoli eliminati") layout.addWidget(tabs) self._output = QPlainTextEdit() self._output.setReadOnly(True) self._output.setStyleSheet("background:#0a0a12;color:#00ff88;font-family:monospace;font-size:11px;") self._output.setMaximumHeight(150) layout.addWidget(self._output) def load_status(self): try: branch = subprocess.check_output( ["git", "rev-parse", "--abbrev-ref", "HEAD"], cwd=self._repo_path, text=True, ).strip() self._branch_label.setText(f"Branch: {branch}") status = subprocess.check_output( ["git", "status", "--short"], cwd=self._repo_path, text=True, ) log = subprocess.check_output( ["git", "log", "--oneline", "-5"], cwd=self._repo_path, text=True, ) self._status_log.setPlainText(f"--- git status ---\n{status}\n--- ultimi commit ---\n{log}") self._deleted_list.clear() deleted = subprocess.check_output( ["git", "log", "--diff-filter=D", "--name-only", "--pretty=format:%H %s", "--", "content/"], cwd=self._repo_path, text=True, ) current_hash = None for line in deleted.splitlines(): if line.strip() == "": continue if line.startswith("content/"): if current_hash: item = QListWidgetItem(f"{line} [{current_hash[:8]}]") item.setData(256, (current_hash, line)) self._deleted_list.addItem(item) else: parts = line.split(" ", 1) current_hash = parts[0] if parts else None except Exception as e: self._output.appendPlainText(f"[Errore] {e}") def _run_worker(self, worker): self._worker = worker worker.output.connect(self._output.appendPlainText) worker.error.connect(lambda e: self._output.appendPlainText(f"[ERRORE] {e}")) worker.finished.connect(lambda ok: self.refresh_needed.emit() if ok else None) worker.start() def _do_pull(self): self._run_worker(GitWorker.pull(self._repo_path, self)) def _do_push_master(self): self._run_worker(GitWorker.push_master(self._repo_path, self)) def _do_push_production(self): self._run_worker(GitWorker.push_production(self._repo_path, self)) def _do_restore(self): item = self._deleted_list.currentItem() if not item: return commit_hash, rel_path = item.data(256) worker = GitWorker.restore_article(self._repo_path, commit_hash, rel_path, self) self._run_worker(worker) self.load_status()