Procházet zdrojové kódy

add signals to indexer and update music folders status

Olivier Massot před 4 roky
rodič
revize
7295278ed2
10 změnil soubory, kde provedl 1019 přidání a 404 odebrání
  1. 35 12
      core/indexer.py
  2. 7 0
      main.py
  3. 0 2
      notes
  4. 3 0
      ui/qt/rsc.qrc
  5. binární
      ui/qt/rsc/invalid.png
  6. binární
      ui/qt/rsc/unknown.png
  7. binární
      ui/qt/rsc/valid.png
  8. 953 379
      ui/qt/rsc_rc.py
  9. 5 0
      ui/qt/widgets/explorertable.py
  10. 16 11
      ui/window.py

+ 35 - 12
core/indexer.py

@@ -4,6 +4,7 @@ from queue import Queue
 from threading import Thread, Lock
 
 import vlc
+from PyQt5.QtCore import pyqtSignal, QObject
 from path import Path
 
 from core import db
@@ -23,24 +24,29 @@ class CyclicThread(Thread):
         Thread.__init__(self)
         self.interrupted = False
         self.last_exec = 0
+        self.running = False
 
     def act(self):
         raise NotImplementedError()
 
     def run(self):
         t = None
-        while 1:
-            if self.DELAY:
-                t = time.time()
+        self.running = True
+        try:
+            while 1:
+                if self.DELAY:
+                    t = time.time()
 
-            if not self.DELAY or not self.last_exec or (t - self.last_exec) > self.DELAY:
-                self.act()
-                self.last_exec = t
+                if not self.DELAY or not self.last_exec or (t - self.last_exec) > self.DELAY:
+                    self.act()
+                    self.last_exec = t
 
-            if self.interrupted:
-                break
+                if self.interrupted:
+                    break
 
-            time.sleep(0.1)
+                time.sleep(0.1)
+        finally:
+            self.running = False
 
     def trigger(self):
         self.last_exec = 0
@@ -49,6 +55,11 @@ class CyclicThread(Thread):
         self.interrupted = True
 
 
+class Emitter(QObject):
+    filesIndexed = pyqtSignal(list)
+    musicFolderStatusChanged = pyqtSignal(int)
+
+
 class Discoverer(CyclicThread):
     DELAY = 5
 
@@ -69,6 +80,18 @@ class Discoverer(CyclicThread):
         for music_folder in music_folders:
             music_folder_path = Path(music_folder.path)
 
+            if not music_folder_path.exists():
+                if music_folder.status == music_folder.STATUS_FOUND:
+                    music_folder.status = music_folder.STATUS_UNAVAILABLE
+                    music_folder_repo.commit()
+                    self.indexer.emitter.musicFolderStatusChanged.emit(music_folder.id)
+                continue
+
+            if music_folder.status != music_folder.STATUS_FOUND:
+                music_folder.status = music_folder.STATUS_FOUND
+                music_folder_repo.commit()
+                self.indexer.emitter.musicFolderStatusChanged.emit(music_folder.id)
+
             for filename in music_folder_path.walkfiles():
                 if self.indexer.in_deque(filename):
                     continue
@@ -88,7 +111,6 @@ class Discoverer(CyclicThread):
             if not filename.exists() and track.status != Track.STATUS_UNAVAILABLE:
                 self.indexer.put(track.id)
 
-
 class Indexer(CyclicThread):
     DELAY = 2
     BUFFER_SIZE = 100
@@ -100,6 +122,7 @@ class Indexer(CyclicThread):
         self.discoverer = Discoverer(self)
         self.last_commit = None
         self.tracks = []
+        self.emitter = Emitter()
 
     def start(self):
         logger.info('** indexation thread started **')
@@ -125,9 +148,9 @@ class Indexer(CyclicThread):
             for track in buffer:
                 if track.id is None:
                     track_repo.create(track)
-
-            logger.info(f"{len(buffer)} tracks indexed")
             track_repo.commit()
+            self.emitter.filesIndexed.emit(buffer)
+            logger.info(f"{len(buffer)} tracks indexed")
 
     def put(self, filename_or_track_id):
         self.deque.appendleft(filename_or_track_id)

+ 7 - 0
main.py

@@ -55,7 +55,14 @@ app = QApplication(sys.argv)
 indexer = Indexer()
 indexer.start()
 main_window = MainWindow(settings)
+
+# connect indexer signals
+indexer.emitter.filesIndexed.connect(main_window.filesIndexed)
+indexer.emitter.musicFolderStatusChanged.connect(main_window.musicFolderStatusChanged)
+
+
 main_window.show()
+
 try:
     r = app.exec_()
 finally:

+ 0 - 2
notes

@@ -12,8 +12,6 @@ Bugs:
       File "E:\dev\mew\core\indexer.py", line 159, in index
         track_repo.commit()
       sqlite3.ProgrammingError: SQLite objects created in a thread can only be used in that same thread. The object was created in thread id 4136 and this is thread id 16548.
-* corriger le pbm d'accès et la lenteur causé par les accès en base de l'indexer
-* bug: si un répertoire de musique est inaccessible, l'indexer plante.
 
 Priorité 1:
 

+ 3 - 0
ui/qt/rsc.qrc

@@ -1,5 +1,8 @@
 <RCC>
   <qresource prefix="/img">
+    <file>rsc/unknown.png</file>
+    <file>rsc/valid.png</file>
+    <file>rsc/invalid.png</file>
     <file>rsc/audio-file.png</file>
     <file>rsc/filter.png</file>
     <file>rsc/search.png</file>

binární
ui/qt/rsc/invalid.png


binární
ui/qt/rsc/unknown.png


binární
ui/qt/rsc/valid.png


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 953 - 379
ui/qt/rsc_rc.py


+ 5 - 0
ui/qt/widgets/explorertable.py

@@ -62,6 +62,11 @@ class ExplorerTable(QTreeWidget):
         self.setUpdatesEnabled(True)
         self.trackSelected.emit(None)
 
+    def update_tracks(self, tracks):
+        # for track in tracks:
+        #     pass
+        self.populate()
+
     def selected_track(self):
         track_id = self.selectionModel().selection().indexes()[2].data(2)
         if not track_id:

+ 16 - 11
ui/window.py

@@ -136,8 +136,11 @@ class MainWindow(QMainWindow):
     def indexation_ended(self):
         self.ui.statusbar.setStatusTip("Indexation terminée.")
 
-    def refresh_explorer_tree(self):
-        self.ui.explorerTable.populate()
+    def refresh_explorer_tree(self, tracks=None):
+        if tracks:
+            self.ui.explorerTable.update_tracks(tracks)
+        else:
+            self.ui.explorerTable.populate()
         self.ui.explorerLineSearch.clear()
 
     def newTrackSelected(self, track=None):
@@ -196,10 +199,11 @@ class MainWindow(QMainWindow):
         music_folders = MusicFolderRepository().get_all()
         self.ui.settingsMusicFoldersTable.setRowCount(0)
         self.ui.settingsMusicFoldersTable.setRowCount(len(music_folders))
+
         music_folder_statuses = [
-            ('Inconnu', 'status_unknown.png'),
-            ('Valide', 'status_found.png'),
-            ('Inaccessible', 'status_unavailable.png')
+            ('Inconnu', ':/img/rsc/unknown.png'),
+            ('Valide', ':/img/rsc/valid.png'),
+            ('Inaccessible', ':/img/rsc/invalid.png')
         ]
         for i, music_folder in enumerate(music_folders):
             self.ui.settingsMusicFoldersTable.setItem(i, 0, QTableWidgetItem(music_folder.id))
@@ -334,12 +338,6 @@ class MainWindow(QMainWindow):
         self.ui.explorerPlaylist.set_is_playing(None)
         self.ui.sessionPlaylist.set_is_playing(None)
 
-    # def showTagsEditor(self):
-    #     track = self.selected_track or None
-    #     tags = DlgTagEditor.select(track, self)
-    #     if tags:
-    #         print(tags)
-
     def addTrackTags(self, tag_id):
         track_id = self.selected_track.id
         track_tag_repo = TrackTagRepository()
@@ -366,6 +364,13 @@ class MainWindow(QMainWindow):
         searchText = self.ui.explorerLineSearch.text()
         self.ui.explorerTable.filterBySearchText(searchText)
 
+    def filesIndexed(self, tracks):
+        self.statusBar().showMessage(f"{len(tracks)} fichiers indexés", 3000)
+        self.refresh_explorer_tree(tracks)
+
+    def musicFolderStatusChanged(self, music_folder_id):
+        self.populate_music_folders_table()
+
     def currentSettings(self):
         volume = self.ui.vlcFrame.volume
         playlist_id = self.selected_playlist.id if self.selected_playlist else None

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů