Jelajahi Sumber

Merge branch 'master' of https://git.xorion.net/olinox14/mew

 Conflicts:
	ui/qt/rsc_rc.py
olinox 4 tahun lalu
induk
melakukan
0236ee5588
11 mengubah file dengan 487 tambahan dan 1412 penghapusan
  1. 35 12
      core/indexer.py
  2. 7 0
      main.py
  3. 0 2
      notes
  4. 3 0
      ui/qt/rsc.qrc
  5. TEMPAT SAMPAH
      ui/qt/rsc/invalid.png
  6. TEMPAT SAMPAH
      ui/qt/rsc/unknown.png
  7. TEMPAT SAMPAH
      ui/qt/rsc/valid.png
  8. 375 1366
      ui/qt/rsc_rc.py
  9. 5 0
      ui/qt/widgets/explorertable.py
  10. 36 3
      ui/qt/widgets/frame_notes.py
  11. 26 29
      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>

TEMPAT SAMPAH
ui/qt/rsc/invalid.png


TEMPAT SAMPAH
ui/qt/rsc/unknown.png


TEMPAT SAMPAH
ui/qt/rsc/valid.png


File diff ditekan karena terlalu besar
+ 375 - 1366
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:

+ 36 - 3
ui/qt/widgets/frame_notes.py

@@ -1,14 +1,19 @@
 from PyQt5 import QtWidgets
 from PyQt5.QtCore import pyqtSignal
 from PyQt5.QtGui import QFont
-from PyQt5.QtWidgets import QTextEdit
+from PyQt5.QtWidgets import QTextEdit, QApplication
 
+from core.repositories import SessionRepository
 from ui.qt.widgets.frame_notes_ui import Ui_frameNotes
 
 
 class FrameNotes(QtWidgets.QFrame):
+    notesChanged = pyqtSignal()
+
     def __init__(self, parent=None):
         super().__init__(parent)
+        self.dirty = False
+        self.playlist = None
         self.createWidgets()
 
     def createWidgets(self):
@@ -33,6 +38,9 @@ class FrameNotes(QtWidgets.QFrame):
         self.ui.btnUndo.clicked.connect(self.ui.sessionNotes.undo)
         self.ui.btnRedo.clicked.connect(self.ui.sessionNotes.redo)
 
+        self.ui.sessionNotes.textChanged.connect(self.notes_changed)
+        QtWidgets.qApp.focusChanged.connect(self.focus_changed)
+
         # A list of all format-related widgets/actions, so we can disable/enable signals when updating.
         self._format_actions = [
             self.ui.btnBold,
@@ -63,9 +71,34 @@ class FrameNotes(QtWidgets.QFrame):
         """
         # # Disable signals for all format widgets, so changing values here does not trigger further formatting.
         self._block_signals(self._format_actions, True)
-
         self.ui.btnItalic.setChecked(self.ui.sessionNotes.fontItalic())
         self.ui.btnItalic.setChecked(self.ui.sessionNotes.fontUnderline())
         self.ui.btnBold.setChecked(self.ui.sessionNotes.fontWeight() == QFont.Bold)
-
         self._block_signals(self._format_actions, False)
+
+    def notes(self):
+        return self.ui.sessionNotes.toHtml()
+
+    def set_notes(self, html):
+        self.ui.sessionNotes.textChanged.disconnect(self.notes_changed)
+        self.ui.sessionNotes.setHtml(html)
+        self.ui.sessionNotes.textChanged.connect(self.notes_changed)
+
+    def set_playlist(self, playlist):
+        self.playlist = playlist
+        self.set_notes(playlist.notes)
+
+    def focus_changed(self, old, now):
+        if old is self.ui.sessionNotes and self.dirty:
+            self.save()
+
+    def notes_changed(self):
+        self.dirty = True
+
+    def save(self):
+        print("save notes")
+        notes = self.notes()
+        session_repo = SessionRepository()
+        self.playlist.notes = notes
+        session_repo.commit()
+        self.dirty = False

+ 26 - 29
ui/window.py

@@ -4,7 +4,7 @@
 
     @author:[author], [year]
 """
-
+from PyQt5 import QtWidgets
 from path import Path
 
 from PyQt5.QtGui import QIcon
@@ -57,6 +57,8 @@ class MainWindow(QMainWindow):
             item.index = i
             self.ui.menu.addItem(item)
 
+        QtWidgets.qApp.focusChanged.connect(self.focus_changed)
+
         # Menu item clicked
         self.ui.menu.itemClicked.connect(self.menu_item_selected)
 
@@ -64,8 +66,6 @@ class MainWindow(QMainWindow):
         self.ui.sessionPlaylist.trackDoubleClicked.connect(self.play_playlist)
         self.ui.sessionBtnChange.clicked.connect(self.selectPlaylist)
 
-        self.ui.frameNotes.ui.sessionNotes.textChanged.connect(self.sessionNotesChanged)
-
         self.ui.btnSessionStart.clicked.connect(self.play_playlist)
 
         # Page 3 - explorer
@@ -84,7 +84,6 @@ class MainWindow(QMainWindow):
         self.ui.explorerTrackTagsTable.tagUnchecked.connect(self.removeTrackTags)
 
         self.ui.explorerTrackMetaStack.setCurrentIndex(0)
-        self.ui.explorerTrackNotepad.textChanged.connect(self.explorerTrackNotesChanged)
         self.ui.explorerTrackPlay.clicked.connect(self.explorerPlaySelected)
 
         self.ui.btnSelectPlaylist.clicked.connect(self.selectPlaylist)
@@ -123,6 +122,10 @@ class MainWindow(QMainWindow):
                 playlist = playlist_repo.get_by_id(playlist_id)
                 self.loadPlaylist(playlist)
 
+    def focus_changed(self, old, new):
+        if old is self.ui.explorerTrackNotepad:
+            self.saveTrackNotes()
+
     def menu_item_selected(self, e):
         self.ui.stack.setCurrentIndex(e.index)
 
@@ -132,8 +135,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):
@@ -153,9 +159,7 @@ class MainWindow(QMainWindow):
         # track infos
         self.update_meta()
 
-        self.ui.explorerTrackNotepad.textChanged.disconnect(self.explorerTrackNotesChanged)
         self.ui.explorerTrackNotepad.setHtml(track.note)
-        self.ui.explorerTrackNotepad.textChanged.connect(self.explorerTrackNotesChanged)
 
         self.ui.explorerTrackTagsTable.populate(track)
 
@@ -194,10 +198,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))
@@ -276,9 +281,7 @@ class MainWindow(QMainWindow):
         self.ui.sessionLblTitle.setText(playlist.name)
         self.ui.sessionPlaylist.populate(playlist)
 
-        self.ui.frameNotes.ui.sessionNotes.textChanged.disconnect(self.sessionNotesChanged)
-        self.ui.frameNotes.ui.sessionNotes.setHtml(playlist.notes)
-        self.ui.frameNotes.ui.sessionNotes.textChanged.connect(self.sessionNotesChanged)
+        self.ui.frameNotes.set_playlist(playlist)
 
         # explorer page
         self.ui.explorerPlaylist.setEnabled(True)
@@ -334,12 +337,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()
@@ -353,26 +350,26 @@ class MainWindow(QMainWindow):
         track_tag_repo.query().filter(TrackTag.track_id == track_id).filter(TrackTag.tag_id == tag_id).delete()
         track_tag_repo.commit()
 
-    def sessionNotesChanged(self):
-        if not self.selected_playlist:
-            return
-        notes = self.ui.frameNotes.ui.sessionNotes.toHtml()
-        session_repo = SessionRepository()
-        self.selected_playlist.notes = notes
-        session_repo.commit()
-
-    def explorerTrackNotesChanged(self):
+    def saveTrackNotes(self):
         if not self.selected_track:
             return
         note = self.ui.explorerTrackNotepad.toHtml()
         track_repo = TrackRepository()
         self.selected_track.note = note
         track_repo.commit()
+        print('track notes saved')
 
     def explorerSearchChanged(self):
         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

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini