2
2
''' system tray '''
3
3
4
4
import logging
5
+ import sqlite3
5
6
6
7
from PySide6 .QtWidgets import ( # pylint: disable=no-name-in-module
7
8
QApplication , QErrorMessage , QMenu , QMessageBox , QSystemTrayIcon )
8
9
from PySide6 .QtGui import QAction , QActionGroup , QIcon # pylint: disable=no-name-in-module
9
- from PySide6 .QtCore import QFileSystemWatcher # pylint: disable=no-name-in-module
10
+ from PySide6 .QtCore import QFileSystemWatcher , QThread # pylint: disable=no-name-in-module
10
11
11
12
import nowplaying .apicache
12
13
import nowplaying .config
19
20
LASTANNOUNCED : dict [str ,str | None ] = {'artist' : None , 'title' : None }
20
21
21
22
23
+ class DatabaseVacuumThread (QThread ): # pylint: disable=too-few-public-methods
24
+ ''' Background thread for database vacuum operations '''
25
+
26
+ def __init__ (self , requestswindow = None ) -> None :
27
+ super ().__init__ ()
28
+ self .requestswindow = requestswindow
29
+
30
+ def run (self ) -> None :
31
+ ''' Perform database vacuum operations in background '''
32
+ logging .debug ("Starting database vacuum operations in background thread" )
33
+
34
+ # Vacuum API cache database
35
+ try :
36
+ nowplaying .apicache .APIResponseCache .vacuum_database_file ()
37
+ logging .debug ("API cache database vacuumed successfully" )
38
+ except (sqlite3 .Error , OSError ) as error :
39
+ logging .error ("Error vacuuming API cache: %s" , error )
40
+ except Exception as error : # pylint: disable=broad-exception-caught
41
+ logging .exception ("Unexpected error vacuuming API cache: %s" , error )
42
+
43
+ # Vacuum metadata database
44
+ try :
45
+ metadb = nowplaying .db .MetadataDB ()
46
+ metadb .vacuum_database ()
47
+ logging .debug ("Metadata database vacuumed successfully" )
48
+ except (sqlite3 .Error , OSError ) as error :
49
+ logging .error ("Error vacuuming metadata database: %s" , error )
50
+ except Exception as error : # pylint: disable=broad-exception-caught
51
+ logging .exception ("Unexpected error vacuuming metadata database: %s" , error )
52
+
53
+ # Vacuum requests database (if available)
54
+ try :
55
+ if self .requestswindow :
56
+ self .requestswindow .vacuum_database ()
57
+ logging .debug ("Requests database vacuumed successfully" )
58
+ except (sqlite3 .Error , OSError ) as error :
59
+ logging .error ("Error vacuuming requests database: %s" , error )
60
+ except Exception as error : # pylint: disable=broad-exception-caught
61
+ logging .exception ("Unexpected error vacuuming requests database: %s" , error )
62
+
63
+ logging .debug ("Database vacuum operations completed in background thread" )
64
+
65
+
22
66
class Tray : # pylint: disable=too-many-instance-attributes
23
67
''' System Tray object '''
24
68
@@ -43,14 +87,17 @@ def __init__(self, beam: bool = False) -> None: #pylint: disable=too-many-state
43
87
self .about_action .setEnabled (True )
44
88
self .about_action .triggered .connect (self .aboutwindow .show )
45
89
46
- # Vacuum databases on startup to reclaim space from previous session
47
- self ._vacuum_databases_on_startup ()
90
+ # Vacuum databases will be started in background after requestswindow is created
48
91
49
92
self .subprocesses = nowplaying .subprocesses .SubprocessManager (self .config )
50
93
try :
51
94
self .settingswindow = nowplaying .settingsui .SettingsUI (tray = self , beam = beam )
95
+ except (FileNotFoundError , ImportError ) as error :
96
+ logging .error ("Failed to create settings window - missing UI files: %s" , error )
97
+ self ._show_installation_error ('settings UI files' )
98
+ return
52
99
except Exception as error : # pylint: disable=broad-exception-caught
53
- logging .error ( "Failed to create settings window: %s" , error )
100
+ logging .exception ( "Unexpected error creating settings window: %s" , error )
54
101
self ._show_installation_error ('settings UI files' )
55
102
return
56
103
@@ -99,6 +146,9 @@ def __init__(self, beam: bool = False) -> None: #pylint: disable=too-many-state
99
146
self .requestswindow = None
100
147
self ._configure_twitchrequests ()
101
148
149
+ # Start database vacuum operations in background thread now that requestswindow is created
150
+ self ._vacuum_databases_on_startup ()
151
+
102
152
def _configure_beamstatus (self , beam : bool ) -> None :
103
153
self .config .cparser .setValue ('control/beam' , beam )
104
154
# these will get filled in by their various subsystems as required
@@ -125,38 +175,16 @@ def _show_installation_error(ui_file: str) -> None:
125
175
app .exit (1 )
126
176
127
177
def _vacuum_databases_on_startup (self ) -> None :
128
- ''' Vacuum databases on startup to reclaim space from previous session '''
129
- logging .debug ("Starting database vacuum operations on startup " )
178
+ ''' Start database vacuum operations in background thread '''
179
+ logging .debug ("Starting database vacuum operations in background thread " )
130
180
131
- # Vacuum API cache database
132
- try :
133
- nowplaying .apicache .APIResponseCache .vacuum_database_file ()
134
- logging .debug ("API cache database vacuumed successfully" )
135
- except Exception as error : # pylint: disable=broad-exception-caught
136
- logging .error ("Error vacuuming API cache: %s" , error )
137
-
138
- # Vacuum metadata database
139
- try :
140
- metadb = nowplaying .db .MetadataDB ()
141
- metadb .vacuum_database ()
142
- logging .debug ("Metadata database vacuumed successfully" )
143
- except Exception as error : # pylint: disable=broad-exception-caught
144
- logging .error ("Error vacuuming metadata database: %s" , error )
145
-
146
- # Vacuum requests database (will be created later, so check if available)
147
- try :
148
- if hasattr (self , 'requestswindow' ) and self .requestswindow :
149
- self .requestswindow .vacuum_database ()
150
- logging .debug ("Requests database vacuumed successfully" )
151
- except Exception as error : # pylint: disable=broad-exception-caught
152
- logging .error ("Error vacuuming requests database: %s" , error )
153
-
154
- logging .debug ("Database vacuum operations completed" )
181
+ # Create and start vacuum thread
182
+ self .vacuum_thread = DatabaseVacuumThread (requestswindow = self .requestswindow )
183
+ self .vacuum_thread .start ()
155
184
156
185
def _requestswindow (self ) -> None :
157
- if self .config .cparser .value ('settings/requests' , type = bool ):
158
- if self .requestswindow :
159
- self .requestswindow .raise_window ()
186
+ if self .config .cparser .value ('settings/requests' , type = bool ) and self .requestswindow :
187
+ self .requestswindow .raise_window ()
160
188
161
189
def _configure_newold_menu (self ) -> None :
162
190
self .action_newestmode .setCheckable (True )
0 commit comments