8
8
import sys
9
9
import sqlite3
10
10
import time
11
- import typing as t
11
+ from typing import TYPE_CHECKING , Any
12
12
13
13
import aiosqlite
14
14
15
+ import watchdog .observers .api # pylint: disable=import-error, no-name-in-module
15
16
from watchdog .observers import Observer # pylint: disable=import-error
16
17
from watchdog .events import PatternMatchingEventHandler # pylint: disable=import-error
17
18
18
19
from PySide6 .QtCore import QStandardPaths # pylint: disable=import-error, no-name-in-module
19
20
21
+ if TYPE_CHECKING :
22
+ from nowplaying .types import TrackMetadata
23
+ import nowplaying .config
24
+
20
25
SPLITSTR = '@@SPLITHERE@@'
21
26
22
27
METADATALIST = [
84
89
class DBWatcher :
85
90
''' utility to watch for database changes '''
86
91
87
- def __init__ (self , databasefile ):
88
- self .observer = None
89
- self .event_handler = None
90
- self .updatetime = time .time ()
91
- self .databasefile = databasefile
92
- self .callback = None
92
+ def __init__ (self , databasefile : str | pathlib . Path ):
93
+ self .observer : watchdog . observers . api . BaseObserver | None = None
94
+ self .event_handler : PatternMatchingEventHandler | None = None
95
+ self .updatetime : float = time .time ()
96
+ self .databasefile : str = str ( databasefile ) # Convert to string for os.path functions
97
+ self .callback : Any = None
93
98
94
99
def start (self , customhandler = None ):
95
100
''' fire up the watcher '''
@@ -137,17 +142,17 @@ def __del__(self):
137
142
class MetadataDB :
138
143
""" Metadata DB module"""
139
144
140
- def __init__ (self , databasefile : t . Optional [ str ] = None , initialize = False ):
141
- self .watchers = set ()
145
+ def __init__ (self , databasefile : str | pathlib . Path | None = None , initialize : bool = False ):
146
+ self .watchers : set [ DBWatcher ] = set ()
142
147
143
- self .databasefile = self .init_db_var (databasefile = databasefile )
148
+ self .databasefile : pathlib . Path = self .init_db_var (databasefile = databasefile )
144
149
logging .debug ("Metadata DB at %s" , self .databasefile )
145
150
if not self .databasefile .exists () or initialize :
146
151
logging .debug ('Setting up a new DB' )
147
152
self .setupsql ()
148
153
149
154
@staticmethod
150
- def init_db_var (databasefile ) -> pathlib .Path :
155
+ def init_db_var (databasefile : str | pathlib . Path | None ) -> pathlib .Path :
151
156
""" split this out to make testing easier """
152
157
if os .environ .get ("WNP_METADB_TEST_FILE" ):
153
158
return pathlib .Path (os .environ ["WNP_METADB_TEST_FILE" ])
@@ -168,13 +173,16 @@ def __del__(self):
168
173
logging .exception ("Clearing leftover watcher" )
169
174
watcher .stop ()
170
175
171
- async def write_to_metadb (self , metadata = None ):
176
+ async def write_to_metadb (self , metadata : "TrackMetadata | None" = None ) -> None :
172
177
''' update metadb '''
173
178
174
- def filterkeys (mydict ) :
179
+ def filterkeys (mydict : dict [ str , Any ]) -> dict [ str , Any ] :
175
180
return {key : mydict [key ] for key in METADATALIST + METADATABLOBLIST if key in mydict }
176
181
177
182
logging .debug ('Called (async) write_to_metadb' )
183
+ if metadata is None :
184
+ logging .debug ('metadata is None' )
185
+ return
178
186
if (not metadata or not METADATALIST or 'title' not in metadata
179
187
or 'artist' not in metadata ):
180
188
logging .debug ('metadata is either empty or too incomplete' )
@@ -186,7 +194,7 @@ def filterkeys(mydict):
186
194
async with aiosqlite .connect (self .databasefile , timeout = 10 ) as connection :
187
195
# do not want to modify the original dictionary
188
196
# otherwise Bad Things(tm) will happen
189
- mdcopy = copy .deepcopy (metadata )
197
+ mdcopy : dict [ str , Any ] = copy .deepcopy (dict ( metadata ) )
190
198
mdcopy ['artistfanartraw' ] = None
191
199
192
200
# toss any keys we do not care about
@@ -214,7 +222,7 @@ def filterkeys(mydict):
214
222
await cursor .execute (sql , datatuple )
215
223
await connection .commit ()
216
224
217
- def make_previoustracklist (self ):
225
+ def make_previoustracklist (self ) -> list [ dict [ str , str ]] | None :
218
226
''' create a reversed list of the tracks played '''
219
227
220
228
if not self .databasefile .exists ():
@@ -237,7 +245,7 @@ def make_previoustracklist(self):
237
245
238
246
return previouslist
239
247
240
- async def make_previoustracklist_async (self ):
248
+ async def make_previoustracklist_async (self ) -> list [ dict [ str , str ]] | None :
241
249
''' create a reversed list of the tracks played '''
242
250
243
251
if not self .databasefile .exists ():
@@ -262,9 +270,9 @@ async def make_previoustracklist_async(self):
262
270
return previouslist
263
271
264
272
@staticmethod
265
- def _postprocess_read_last_meta (row ) :
273
+ def _postprocess_read_last_meta (row : sqlite3 . Row ) -> "TrackMetadata" :
266
274
''' common post-process of read_last_meta '''
267
- metadata = {data : row [data ] for data in METADATALIST }
275
+ metadata : dict [ str , Any ] = {data : row [data ] for data in METADATALIST }
268
276
for key in METADATABLOBLIST :
269
277
metadata [key ] = row [key ]
270
278
if not metadata [key ]:
@@ -276,9 +284,9 @@ def _postprocess_read_last_meta(row):
276
284
metadata [key ] = metadata [key ].split (SPLITSTR )
277
285
278
286
metadata ['dbid' ] = row ['id' ]
279
- return metadata
287
+ return metadata # type: ignore[return-value]
280
288
281
- async def read_last_meta_async (self ):
289
+ async def read_last_meta_async (self ) -> "TrackMetadata | None" :
282
290
''' update metadb '''
283
291
284
292
if not self .databasefile .exists ():
@@ -302,10 +310,10 @@ async def read_last_meta_async(self):
302
310
return None
303
311
304
312
metadata = self ._postprocess_read_last_meta (row )
305
- metadata ['previoustrack' ] = await self .make_previoustracklist_async ()
313
+ metadata ['previoustrack' ] = await self .make_previoustracklist_async () # type: ignore[misc]
306
314
return metadata
307
315
308
- def read_last_meta (self ):
316
+ def read_last_meta (self ) -> "TrackMetadata | None" :
309
317
''' update metadb '''
310
318
311
319
if not self .databasefile .exists ():
@@ -326,7 +334,7 @@ def read_last_meta(self):
326
334
return None
327
335
328
336
metadata = self ._postprocess_read_last_meta (row )
329
- metadata ['previoustrack' ] = self .make_previoustracklist ()
337
+ metadata ['previoustrack' ] = self .make_previoustracklist () # type: ignore[misc]
330
338
return metadata
331
339
332
340
def setupsql (self ):
@@ -369,7 +377,8 @@ def vacuum_database(self):
369
377
logging .error ("Database error during vacuum: %s" , error )
370
378
371
379
372
- def create_setlist (config = None , databasefile = None ):
380
+ def create_setlist (config : "nowplaying.config.ConfigFile | None" = None ,
381
+ databasefile : str | None = None ) -> None :
373
382
''' create the setlist '''
374
383
375
384
if not config :
@@ -385,7 +394,7 @@ def create_setlist(config=None, databasefile=None):
385
394
logging .info ('No tracks were played; not saving setlist' )
386
395
return
387
396
388
- previoustrack = metadata ['previoustrack' ]
397
+ previoustrack = metadata ['previoustrack' ] # type: ignore[misc]
389
398
if not previoustrack :
390
399
logging .info ('No previoustracks were played; not saving setlist' )
391
400
return
0 commit comments