recent uploads

This commit is contained in:
2026-08-11 22:36:40 +02:00
parent e4d82e1c7e
commit 90bbcd1072

249
gui.py
View File

@@ -24,17 +24,41 @@ def normalize_file_path(path_str: str) -> str:
path_str = urllib.parse.unquote(path_str[7:])
return os.path.abspath(path_str)
from PySide6.QtCore import Qt, QThread, QObject, Signal, QUrl, QFile, QIODevice
from PySide6.QtGui import QIcon, QAction, QPixmap, QPainter, QColor, QFont, QPen, QImage
from PySide6.QtGui import QIcon, QAction, QPixmap, QPainter, QColor, QFont, QPen, QImage, QDesktopServices
from PySide6.QtNetwork import QNetworkAccessManager, QNetworkRequest, QHttpMultiPart, QHttpPart, QNetworkReply, QLocalServer, QLocalSocket
from PySide6.QtWidgets import (
QApplication, QSystemTrayIcon, QMenu, QDialog, QVBoxLayout, QHBoxLayout,
QLabel, QLineEdit, QComboBox, QCheckBox, QPushButton, QGroupBox,
QFormLayout, QMessageBox, QFileDialog, QSlider
QFormLayout, QMessageBox, QFileDialog, QSlider, QScrollArea, QFrame, QGridLayout, QWidget
)
# Configuration paths
CONFIG_DIR = os.path.expanduser("~/.config/f0ckm-uploader")
CONFIG_PATH = os.path.join(CONFIG_DIR, "config.json")
HISTORY_PATH = os.path.join(CONFIG_DIR, "history.json")
def load_history():
if not os.path.exists(HISTORY_PATH):
return []
try:
with open(HISTORY_PATH, "r", encoding="utf-8") as f:
return json.load(f)
except Exception:
return []
def save_history(history_list):
try:
os.makedirs(CONFIG_DIR, exist_ok=True)
with open(HISTORY_PATH, "w", encoding="utf-8") as f:
json.dump(history_list[:100], f, indent=2)
except Exception as e:
print(f"Error saving history: {e}")
def add_history_entry(entry):
history = load_history()
history = [h for h in history if h.get("url") != entry.get("url")]
history.insert(0, entry)
save_history(history)
DEFAULT_CONFIG = {
"api_url": "",
@@ -509,6 +533,201 @@ class SettingsDialog(QDialog):
else:
QMessageBox.critical(self, "Error", "Failed to save configuration file.")
# ==========================================
# Upload Gallery Window & Components
# ==========================================
class GalleryCard(QFrame):
def __init__(self, item, parent=None, on_delete=None):
super().__init__(parent)
self.item = item
self.on_delete = on_delete
self.setFrameShape(QFrame.StyledPanel)
self.setFixedHeight(195)
self.setStyleSheet("""
GalleryCard {
background-color: #1e1e24;
border: 1px solid #333340;
border-radius: 8px;
}
GalleryCard:hover {
border: 1px solid #555575;
background-color: #242430;
}
""")
layout = QVBoxLayout(self)
layout.setContentsMargins(8, 8, 8, 8)
layout.setSpacing(6)
# Thumbnail
self.thumb_label = QLabel()
self.thumb_label.setFixedSize(160, 100)
self.thumb_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.thumb_label.setStyleSheet("background-color: #121216; border-radius: 4px;")
thumb_path = item.get("thumbnail_path", "")
file_path = item.get("file_path", "")
pixmap = None
if thumb_path and os.path.exists(thumb_path):
pixmap = QPixmap(thumb_path)
elif file_path and os.path.exists(file_path):
gen_thumb = generate_thumbnail(file_path)
if gen_thumb and os.path.exists(gen_thumb):
pixmap = QPixmap(gen_thumb)
if pixmap and not pixmap.isNull():
scaled = pixmap.scaled(160, 100, Qt.AspectRatioMode.KeepAspectRatioByExpanding, Qt.TransformationMode.SmoothTransformation)
x = max(0, (scaled.width() - 160) // 2)
y = max(0, (scaled.height() - 100) // 2)
self.thumb_label.setPixmap(scaled.copy(x, y, 160, 100))
else:
self.thumb_label.setText("No Preview")
self.thumb_label.setStyleSheet("background-color: #121216; color: #666; font-size: 11px;")
layout.addWidget(self.thumb_label)
# Filename
fname = item.get("filename", "File")
lbl_name = QLabel(fname)
lbl_name.setStyleSheet("font-weight: bold; font-size: 11px; color: #e0e0e0;")
lbl_name.setToolTip(item.get("filename", ""))
layout.addWidget(lbl_name)
# Timestamp
ts = item.get("timestamp", 0)
dt_str = time.strftime("%Y-%m-%d %H:%M", time.localtime(ts)) if ts else ""
lbl_time = QLabel(dt_str)
lbl_time.setStyleSheet("font-size: 9px; color: #8888a0;")
layout.addWidget(lbl_time)
# Action Buttons
btn_layout = QHBoxLayout()
btn_layout.setSpacing(4)
btn_copy = QPushButton("Copy")
btn_copy.setToolTip("Copy URL to clipboard")
btn_copy.setStyleSheet("font-size: 10px; padding: 4px 6px;")
btn_copy.clicked.connect(self.on_copy_link)
btn_open = QPushButton("Open")
btn_open.setToolTip("Open link in browser")
btn_open.setStyleSheet("font-size: 10px; padding: 4px 6px;")
btn_open.clicked.connect(self.on_open_url)
btn_del = QPushButton("")
btn_del.setToolTip("Remove from history")
btn_del.setStyleSheet("font-size: 10px; padding: 4px 6px; color: #ff6666;")
btn_del.clicked.connect(self.on_remove_item)
btn_layout.addWidget(btn_copy)
btn_layout.addWidget(btn_open)
btn_layout.addWidget(btn_del)
layout.addLayout(btn_layout)
def on_copy_link(self):
url = self.item.get("url", "")
if url:
QApplication.clipboard().setText(url)
def on_open_url(self):
url = self.item.get("url", "")
if url:
QDesktopServices.openUrl(QUrl(url))
def on_remove_item(self):
if self.on_delete:
self.on_delete(self.item)
class GalleryWindow(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("f0ckm Upload Gallery")
self.resize(760, 560)
app_icon = get_app_icon()
if not app_icon.isNull():
self.setWindowIcon(app_icon)
self.init_ui()
def init_ui(self):
main_layout = QVBoxLayout(self)
main_layout.setContentsMargins(15, 15, 15, 15)
main_layout.setSpacing(12)
# Header bar
header_layout = QHBoxLayout()
lbl_title = QLabel("Recent Uploads")
lbl_title.setStyleSheet("font-size: 16px; font-weight: bold; color: #ffffff;")
header_layout.addWidget(lbl_title)
header_layout.addStretch()
self.txt_search = QLineEdit()
self.txt_search.setPlaceholderText("Search uploads...")
self.txt_search.setFixedWidth(200)
self.txt_search.textChanged.connect(self.load_items)
header_layout.addWidget(self.txt_search)
btn_clear = QPushButton("Clear History")
btn_clear.clicked.connect(self.on_clear_history)
header_layout.addWidget(btn_clear)
main_layout.addLayout(header_layout)
# Scroll Area for Gallery Cards
self.scroll_area = QScrollArea()
self.scroll_area.setWidgetResizable(True)
self.scroll_area.setStyleSheet("QScrollArea { border: 1px solid #333340; background: #141418; border-radius: 6px; }")
self.scroll_content = QWidget()
self.grid_layout = QGridLayout(self.scroll_content)
self.grid_layout.setContentsMargins(12, 12, 12, 12)
self.grid_layout.setSpacing(12)
self.grid_layout.setAlignment(Qt.AlignmentFlag.AlignTop)
self.scroll_area.setWidget(self.scroll_content)
main_layout.addWidget(self.scroll_area)
self.load_items()
def load_items(self):
while self.grid_layout.count():
child = self.grid_layout.takeAt(0)
if child.widget():
child.widget().deleteLater()
history = load_history()
query = self.txt_search.text().strip().lower()
if query:
history = [h for h in history if query in h.get("filename", "").lower() or query in h.get("url", "").lower()]
if not history:
lbl_empty = QLabel("No uploads found.")
lbl_empty.setAlignment(Qt.AlignmentFlag.AlignCenter)
lbl_empty.setStyleSheet("color: #8888a0; font-size: 14px; margin: 40px;")
self.grid_layout.addWidget(lbl_empty, 0, 0)
return
cols = 4
for idx, item in enumerate(history):
card = GalleryCard(item, on_delete=self.delete_item)
row = idx // cols
col = idx % cols
self.grid_layout.addWidget(card, row, col)
def delete_item(self, item):
history = load_history()
history = [h for h in history if h.get("url") != item.get("url")]
save_history(history)
self.load_items()
def on_clear_history(self):
if QMessageBox.question(self, "Clear History", "Are you sure you want to clear your upload history?", QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes:
save_history([])
self.load_items()
# ==========================================
# Dynamic Tray Digit Icon Painter
# ==========================================
@@ -828,6 +1047,10 @@ class SystemTrayApp(QObject):
settings_action.triggered.connect(self.on_open_settings)
self.menu.addAction(settings_action)
gallery_action = QAction("Recent Uploads Gallery", self.menu)
gallery_action.triggered.connect(self.on_open_gallery)
self.menu.addAction(gallery_action)
self.menu.addSeparator()
quit_action = QAction("Quit", self.menu)
@@ -838,6 +1061,15 @@ class SystemTrayApp(QObject):
self.tray.activated.connect(self.on_tray_activated)
self.settings_dialog = None
self.gallery_window = None
def on_open_gallery(self):
if self.gallery_window is None:
self.gallery_window = GalleryWindow()
self.gallery_window.load_items()
self.gallery_window.show()
self.gallery_window.raise_()
self.gallery_window.activateWindow()
def show(self):
self.tray.show()
@@ -975,6 +1207,19 @@ class SystemTrayApp(QObject):
if res.get("success") and res.get("url"):
item_url = res.get("url")
QApplication.clipboard().setText(item_url)
# Add to history gallery
thumb = generate_thumbnail(file_path)
add_history_entry({
"timestamp": time.time(),
"filename": os.path.basename(file_path),
"file_path": file_path,
"url": item_url,
"thumbnail_path": thumb if thumb and os.path.exists(thumb) else ""
})
if hasattr(self, "gallery_window") and self.gallery_window and self.gallery_window.isVisible():
self.gallery_window.load_items()
self.show_success_notification(file_path, item_url)
else:
msg = res.get("msg", "Upload failed")