Skip to content

Commit 860e702

Browse files
committed
App: Add loading state
[skip ci]
1 parent 8cf4217 commit 860e702

1 file changed

Lines changed: 92 additions & 17 deletions

File tree

‎scripts/gdrive_app.py‎

Lines changed: 92 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,17 @@
88
from PySide6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
99
QHBoxLayout, QListWidget, QListWidgetItem,
1010
QPushButton, QLineEdit, QSplitter,
11-
QListView, QMenu)
11+
QListView, QMenu, QProgressDialog)
1212
from PySide6.QtCore import Qt, QSize
1313
from PySide6.QtGui import QIcon, QPixmap, QShortcut, QKeySequence
1414

1515
import pytablericons
1616
from pytablericons.outline_icon import OutlineIcon
1717
from pytablericons.filled_icon import FilledIcon
1818

19-
from gdrive import gcache
2019

2120
from PySide6.QtSvg import QSvgRenderer
22-
from PySide6.QtCore import QByteArray, Qt, QRunnable, Signal, QThreadPool, Slot, QTimer
21+
from PySide6.QtCore import QByteArray, Qt, QRunnable, Signal, QThreadPool, Slot, QTimer, QThread
2322
from PySide6.QtGui import QPainter, QImage
2423

2524
from collections import OrderedDict
@@ -30,6 +29,50 @@
3029
from strutils import thumbnail_path_for_file, THUMBNAIL_SIZES
3130

3231

32+
class GCacheLoaderThread(QThread):
33+
progress_text_changed = Signal(str)
34+
progress_value_changed = Signal(int, int) # current, total
35+
36+
def run(self):
37+
import local_gdrive
38+
import gdrive_base
39+
40+
original_yaspin = getattr(local_gdrive, 'yaspin', None)
41+
original_trange = getattr(gdrive_base, 'trange', None)
42+
43+
class MockYaspin:
44+
def __init__(self_mock, *args, **kwargs):
45+
self_mock.text = kwargs.get('text', args[0] if args else "")
46+
def __enter__(self_mock):
47+
self.progress_text_changed.emit(self_mock.text)
48+
self.progress_value_changed.emit(0, 0)
49+
return self_mock
50+
def __exit__(self_mock, exc_type, exc_val, exc_tb):
51+
pass
52+
def write(self_mock, text):
53+
pass
54+
55+
def mock_trange(*args, **kwargs):
56+
r = range(*args)
57+
total = len(r)
58+
self.progress_value_changed.emit(0, total)
59+
for i, val in enumerate(r):
60+
self.progress_value_changed.emit(i, total)
61+
yield val
62+
self.progress_value_changed.emit(total, total)
63+
64+
local_gdrive.yaspin = MockYaspin
65+
gdrive_base.trange = mock_trange
66+
67+
try:
68+
import gdrive
69+
finally:
70+
if original_yaspin:
71+
local_gdrive.yaspin = original_yaspin
72+
if original_trange:
73+
gdrive_base.trange = original_trange
74+
75+
3376
class ThumbnailWorker(QRunnable):
3477
def __init__(self, item, cancel_flag, emit_callback):
3578
super().__init__()
@@ -144,7 +187,7 @@ def get_mime_icon(mime_type: str) -> QIcon:
144187
elif mime_type == 'application/vnd.google-apps.shortcut+file':
145188
return get_icon(OutlineIcon.FILE_SYMLINK, color="#999999")
146189
elif mime_type == 'application/vnd.google-apps.shortcut+folder':
147-
return get_icon(OutlineIcon.FOLDER_SYMLINK, color="#999999")
190+
return get_icon(OutlineIcon.FOLDER_SYMLINK, color=color)
148191
elif mime_type == 'application/vnd.google-apps.document':
149192
return get_icon(OutlineIcon.FILE_TEXT, color="#4285F4")
150193
elif mime_type == 'application/vnd.google-apps.spreadsheet':
@@ -192,7 +235,30 @@ def __init__(self):
192235
self.queued_thumbnails = set()
193236
self.thumbnail_loaded_signal.connect(self.on_thumbnail_loaded)
194237

238+
self.gcache = None
195239
self.init_ui()
240+
241+
self.progress_dialog = QProgressDialog("Loading GDrive Cache...", "Cancel", 0, 0, self)
242+
self.progress_dialog.setWindowTitle("Please Wait")
243+
self.progress_dialog.setWindowModality(Qt.WindowModal)
244+
self.progress_dialog.setCancelButton(None)
245+
self.progress_dialog.setMinimumDuration(0)
246+
self.progress_dialog.setValue(0)
247+
248+
self.loader_thread = GCacheLoaderThread(self)
249+
self.loader_thread.progress_text_changed.connect(self.progress_dialog.setLabelText)
250+
self.loader_thread.progress_value_changed.connect(self.update_progress)
251+
self.loader_thread.finished.connect(self.on_gcache_loaded)
252+
self.loader_thread.start()
253+
254+
def update_progress(self, current, total):
255+
self.progress_dialog.setMaximum(total)
256+
self.progress_dialog.setValue(current)
257+
258+
def on_gcache_loaded(self):
259+
self.progress_dialog.close()
260+
import gdrive
261+
self.gcache = gdrive.gcache
196262
self.load_root("my_drive")
197263

198264
def init_ui(self):
@@ -272,10 +338,12 @@ def init_ui(self):
272338

273339
self.file_view.setFocus()
274340

275-
def apply_icon_overlay(self, pixmap: QPixmap, icon_enum: Any, color: str = "#999999", is_filled: bool = False) -> QPixmap:
341+
def apply_icon_overlay(self, pixmap: QPixmap, icon_enum: Any, color: str = None, is_filled: bool = False) -> QPixmap:
276342
result = QPixmap(pixmap)
277343
painter = QPainter(result)
278344
painter.setRenderHint(QPainter.Antialiasing)
345+
if not color:
346+
color = QApplication.palette().text().color().name()
279347

280348
overlay_icon = get_icon(icon_enum, color=color, is_filled=is_filled)
281349
overlay_size = pixmap.width() // 4
@@ -285,8 +353,9 @@ def apply_icon_overlay(self, pixmap: QPixmap, icon_enum: Any, color: str = "#999
285353
x = pixmap.width() - overlay_size - 4
286354
y = pixmap.height() - overlay_size - 4
287355

288-
# Draw a white circular background
289-
painter.setBrush(Qt.white)
356+
# Draw a circular background
357+
bg_color = QApplication.palette().window().color().name()
358+
painter.setBrush(bg_color)
290359
painter.setPen(Qt.NoPen)
291360
painter.drawEllipse(x + 2, y + 2, overlay_size - 4, overlay_size - 4)
292361

@@ -296,10 +365,10 @@ def apply_icon_overlay(self, pixmap: QPixmap, icon_enum: Any, color: str = "#999
296365

297366
def load_root(self, root_type: str, add_history=True, highlight_fileid: str | None = None, clicked_item_id: str | None = None):
298367
if root_type == "my_drive":
299-
items = gcache.get_root_my_drive_children()
368+
items = self.gcache.get_root_my_drive_children()
300369
self.address_bar.setText("My Drive")
301370
else:
302-
items = gcache.get_root_shared_with_me_items()
371+
items = self.gcache.get_root_shared_with_me_items()
303372
self.address_bar.setText("Shared with me")
304373

305374
self.current_folder_id = root_type
@@ -313,7 +382,7 @@ def load_root(self, root_type: str, add_history=True, highlight_fileid: str | No
313382
self.file_view.repaint()
314383

315384
def load_folder(self, folder_id: str, folder_name: str, add_history=True, highlight_fileid: str | None=None, clicked_item_id: str | None = None):
316-
items = gcache.get_children(folder_id)
385+
items = self.gcache.get_children(folder_id)
317386
self.current_folder_id = folder_id
318387
self.address_bar.setText(folder_name)
319388
if add_history:
@@ -411,7 +480,7 @@ def populate_files(self, items: List[Dict[str, Any]]):
411480
else:
412481
pixmap = get_mime_icon(mime).pixmap(self.file_view.iconSize())
413482

414-
cache_path = gcache.get_cache_path_for_file(item)
483+
cache_path = self.gcache.get_cache_path_for_file(item)
415484
if cache_path:
416485
if cache_path.exists():
417486
pixmap = self.apply_icon_overlay(pixmap, FilledIcon.CIRCLE_CHECK)
@@ -474,7 +543,7 @@ def on_thumbnail_loaded(self, file_id: str, img: QImage):
474543
item = self.item_mapping[file_id]
475544
if item.listWidget() == self.file_view:
476545
file_data = item.data(Qt.UserRole)
477-
cache_path = gcache.get_cache_path_for_file(file_data)
546+
cache_path = self.gcache.get_cache_path_for_file(file_data)
478547
if cache_path:
479548
if cache_path.exists():
480549
pixmap = self.apply_icon_overlay(pixmap, FilledIcon.CIRCLE_CHECK)
@@ -497,11 +566,17 @@ def on_context_menu(self, pos):
497566

498567
file_data = item.data(Qt.UserRole)
499568
menu = QMenu(self)
569+
copy_id_action = menu.addAction("Copy ID")
570+
copy_link_action = menu.addAction("Copy URL")
500571
open_browser_action = menu.addAction("Open in browser...")
501572

502573
action = menu.exec(self.file_view.viewport().mapToGlobal(pos))
503-
if action == open_browser_action:
504-
url = gdrive_base.GENERIC_LINK_PREFIX + file_data['id']
574+
url = gdrive_base.GENERIC_LINK_PREFIX + file_data['id']
575+
if action == copy_id_action:
576+
QApplication.clipboard().setText(file_data['id'])
577+
elif action == copy_link_action:
578+
QApplication.clipboard().setText(url)
579+
elif action == open_browser_action:
505580
webbrowser.open(url)
506581

507582
def on_item_activated(self, item: QListWidgetItem):
@@ -515,10 +590,10 @@ def on_item_activated(self, item: QListWidgetItem):
515590
folder_id = file_data['shortcutDetails']['targetId']
516591
target_file = None
517592
else:
518-
target_file = gcache.get_item(file_data['shortcutDetails']['targetId'])
593+
target_file = self.gcache.get_item(file_data['shortcutDetails']['targetId'])
519594
folder_id = target_file['parent_id']
520595
target_file = target_file['id']
521-
target_folder = gcache.get_item(folder_id)
596+
target_folder = self.gcache.get_item(folder_id)
522597
if not target_folder:
523598
url = gdrive_base.FOLDER_LINK.format(folder_id)
524599
webbrowser.open(url)
@@ -527,7 +602,7 @@ def on_item_activated(self, item: QListWidgetItem):
527602
self.open_file(file_data)
528603

529604
def open_file(self, file_data: Dict[str, Any]):
530-
cache_path = gcache.get_cache_path_for_file(file_data)
605+
cache_path = self.gcache.get_cache_path_for_file(file_data)
531606
if cache_path and cache_path.exists():
532607
# Open with default app
533608
if sys.platform.startswith('linux'):

0 commit comments

Comments
 (0)