1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
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()
self.load_status()
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)
worker.finished.connect(lambda ok: self.load_status() if ok else None)
self._run_worker(worker)
|