From: Danilo M. Date: Sun, 3 May 2026 08:45:04 +0000 (+0200) Subject: feat: media view with drag-drop upload and clipboard path copy X-Git-Tag: v1.0~8 X-Git-Url: https://git.danix.xyz/?a=commitdiff_plain;h=43119b38a8f8a57894936a07d9a66345139e9a4f;p=publisher.git feat: media view with drag-drop upload and clipboard path copy --- diff --git a/ui/main_window.py b/ui/main_window.py index 61d74e4..d6687ea 100644 --- a/ui/main_window.py +++ b/ui/main_window.py @@ -110,12 +110,11 @@ class MainWindow(QMainWindow): self._stack.addWidget(self._taxonomy_view) self._page_taxonomy = self._stack.count() - 1 - # Remaining placeholders - for name in ["media"]: - w = QLabel(f"[{name}]") - w.setAlignment(Qt.AlignmentFlag.AlignCenter) - self._stack.addWidget(w) - setattr(self, f"_page_{name}", self._stack.count() - 1) + from ui.media_view import MediaView + + self._media_view = MediaView(Path(self.config.blog_repo), parent=self) + self._stack.addWidget(self._media_view) + self._page_media = self._stack.count() - 1 def _build_sidebar(self) -> QWidget: w = QWidget() diff --git a/ui/media_view.py b/ui/media_view.py new file mode 100644 index 0000000..c77b808 --- /dev/null +++ b/ui/media_view.py @@ -0,0 +1,94 @@ +from __future__ import annotations +import shutil +from datetime import date +from pathlib import Path +from PyQt6.QtWidgets import ( + QWidget, QVBoxLayout, QHBoxLayout, + QLabel, QPushButton, QListWidget, QListWidgetItem, QFileDialog, +) +from PyQt6.QtCore import Qt +from PyQt6.QtGui import QDragEnterEvent, QDropEvent + +class MediaView(QWidget): + def __init__(self, blog_root: Path, parent=None): + super().__init__(parent) + self._blog_root = blog_root + self.setAcceptDrops(True) + self._build_ui() + self._refresh_list() + + def _target_dir(self) -> Path: + today = date.today() + return self._blog_root / "static" / "uppies" / str(today.year) / f"{today.month:02d}" + + def _build_ui(self): + layout = QVBoxLayout(self) + + header = QLabel("🖼 Media — static/uppies/YYYY/MM/") + header.setStyleSheet("color:#fff;font-weight:bold;font-size:13px;padding:10px;") + layout.addWidget(header) + + drop_zone = QLabel("Trascina file qui, oppure usa il pulsante sotto.") + drop_zone.setAlignment(Qt.AlignmentFlag.AlignCenter) + drop_zone.setStyleSheet("border:2px dashed #2a2a4e;color:#555;padding:20px;border-radius:6px;margin:10px;") + drop_zone.setMinimumHeight(80) + layout.addWidget(drop_zone) + + btns = QHBoxLayout() + add_btn = QPushButton("📂 Aggiungi file...") + add_btn.clicked.connect(self._pick_files) + btns.addWidget(add_btn) + btns.addStretch() + self._path_label = QLabel("") + self._path_label.setStyleSheet("color:#a855f7;font-size:10px;") + btns.addWidget(self._path_label) + layout.addLayout(btns) + + self._list = QListWidget() + layout.addWidget(self._list, stretch=1) + + self._status = QLabel("") + self._status.setStyleSheet("color:#888;font-size:10px;padding:4px;") + layout.addWidget(self._status) + + def _copy_files(self, paths: list[str]): + target = self._target_dir() + target.mkdir(parents=True, exist_ok=True) + last_web_path = "" + for src in paths: + dest = target / Path(src).name + shutil.copy2(src, dest) + today = date.today() + last_web_path = f"/uppies/{today.year}/{today.month:02d}/{Path(src).name}" + + if last_web_path: + from PyQt6.QtWidgets import QApplication + QApplication.clipboard().setText(last_web_path) + self._status.setText(f"Copiato in clipboard: {last_web_path}") + + self._refresh_list() + + def _pick_files(self): + files, _ = QFileDialog.getOpenFileNames(self, "Seleziona file media") + if files: + self._copy_files(files) + + def _refresh_list(self): + self._list.clear() + target = self._target_dir() + today = date.today() + self._path_label.setText(f"Cartella: static/uppies/{today.year}/{today.month:02d}/") + if not target.exists(): + return + for f in sorted(target.iterdir()): + if f.is_file(): + self._list.addItem(QListWidgetItem(f.name)) + + def dragEnterEvent(self, event: QDragEnterEvent): + if event.mimeData().hasUrls(): + event.acceptProposedAction() + + def dropEvent(self, event: QDropEvent): + paths = [u.toLocalFile() for u in event.mimeData().urls() if u.isLocalFile()] + if paths: + self._copy_files(paths)