Selaa lähdekoodia

various fixes

Olivier Massot 4 vuotta sitten
vanhempi
commit
24921ebc80

+ 7 - 8
core/file_utilities.py

@@ -1,20 +1,19 @@
 import hashlib
 import mimetypes
-import os
-import platform
 import subprocess
 import sys
 
-MEDIA_EXTS_CACHE = ['.mp3', '.wma', '.flac', '.mp4']
+MEDIA_EXTS_CACHE = []
+# MEDIA_EXTS_CACHE = ['.mp3', '.wma', '.flac', '.mp4']
 
 
 def media_exts():
     """ List of media file extensions from local system mimetypes """
-    # if not MEDIA_EXTS_CACHE:
-    #     mimetypes.init()
-    #     for ext in mimetypes.types_map:
-    #         if mimetypes.types_map[ext].split('/')[0] in ('audio', 'video'):
-    #             MEDIA_EXTS_CACHE.append(ext)
+    if not MEDIA_EXTS_CACHE:
+        mimetypes.init()
+        for ext in mimetypes.types_map:
+            if mimetypes.types_map[ext].split('/')[0] in ('audio', 'video'):
+                MEDIA_EXTS_CACHE.append(ext)
     return MEDIA_EXTS_CACHE
 
 

+ 11 - 7
core/indexer.py

@@ -6,7 +6,7 @@ import vlc
 from PyQt5.QtCore import pyqtSignal, QObject
 from path import Path
 
-from core import db
+from core import db, file_utilities
 from core.exceptions import NotSupportedFile
 from core.file_utilities import is_media_file_ext, hash_file
 from core.logging_ import Logger
@@ -37,10 +37,10 @@ class Indexer(Thread):
     def run(self):
         logger.info('** indexation thread started **')
         while not self.stopped.wait(self.DELAY):
+            # logger.debug("... indexation")
             self.act()
 
     def act(self):
-
         # Initialize
         session = db.Session()
         music_folder_repo = MusicFolderRepository(session)
@@ -59,6 +59,7 @@ class Indexer(Thread):
         for music_folder in music_folders:
             music_folder_path = Path(music_folder.path)
 
+            # music folder cant be found
             if not music_folder_path.exists():
                 if music_folder.status == music_folder.STATUS_FOUND:
                     music_folder.status = music_folder.STATUS_UNAVAILABLE
@@ -66,19 +67,24 @@ class Indexer(Thread):
                     self.emitter.musicFolderStatusChanged.emit(music_folder.id)
                 continue
 
+            # music folder found
             if music_folder.status != music_folder.STATUS_FOUND:
                 music_folder.status = music_folder.STATUS_FOUND
                 music_folder_repo.commit()
                 self.emitter.musicFolderStatusChanged.emit(music_folder.id)
 
+            # walk files
             for filename in music_folder_path.walkfiles():
+                # filename already seen
                 if filename in buffer:
                     continue
+                # new file
                 if filename not in index and is_media_file_ext(filename.ext):
                     buffer.append(filename)
+                # file already in db
                 elif filename in index:
                     track = index[filename]
-                    if track.status == Track.STATUS_UNAVAILABLE:
+                    if track.status in (Track.STATUS_UNAVAILABLE, Track.STATUS_UNKNOWN):
                         buffer.append(track.id)
                     del index[filename]
 
@@ -92,6 +98,7 @@ class Indexer(Thread):
                 buffer.append(track.id)
 
         # Index buffered tracks
+        # NB: the tracks are treated from the end to the beginning, so missing files are treated before the new ones
         tracks = []
         while buffer:
             filename_or_id = buffer.pop()
@@ -145,7 +152,6 @@ class Indexer(Thread):
 
         vlc_media = vlc.Media(filename)
         vlc_media.parse()
-        track_infos = vlc_media.get_tracks_info()
 
         title = vlc_media.get_meta(vlc.Meta.Title)
         if not title or title == '(null)':
@@ -155,9 +161,7 @@ class Indexer(Thread):
         track.artist = vlc_media.get_meta(vlc.Meta.AlbumArtist) or vlc_media.get_meta(vlc.Meta.Artist)
         track.album = vlc_media.get_meta(vlc.Meta.Album)
         track.track_num = vlc_media.get_meta(vlc.Meta.TrackNumber)
-        # track.year = vlc_media.get_meta(vlc.Meta.Date)
-        # track.duration = vlc_media.get_meta(vlc.Meta.Date)
-        # track.size = 0
+        track.duration = vlc_media.get_duration() // 1000
         track.note = ""
         track.status = Track.STATUS_FOUND
         track.path = filename

+ 0 - 2
core/models.py

@@ -49,9 +49,7 @@ class Track(Model):
     artist = Column(String)
     album = Column(String)
     track_num = Column(Integer)
-    year = Column(Integer)
     duration = Column(Integer)
-    size = Column(Integer)
     note = Column(String)
     status = Column(Integer, nullable=False, default=0)
     path = Column(String, nullable=False)

+ 0 - 230
core/vlc_.py

@@ -1,230 +0,0 @@
-#
-# PyQt5 example for VLC Python bindings
-# Copyright (C) 2009-2010 the VideoLAN team
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
-#
-"""
-A simple example for VLC python bindings using PyQt5.
-
-Author: Saveliy Yusufov, Columbia University, sy2685@columbia.edu
-Date: 25 December 2018
-"""
-import mimetypes
-import platform
-import os
-import sys
-
-from PyQt5 import QtWidgets, QtGui, QtCore
-
-from core import constants
-
-os.environ['PYTHON_VLC_LIB_PATH'] = constants.APP_ROOT / 'core' / 'vlc-core' / 'libvlc.dll'
-if 1:
-    import vlc
-
-class Player(QtWidgets.QMainWindow):
-    """A simple Media Player using VLC and Qt
-    """
-
-    def __init__(self, master=None):
-        QtWidgets.QMainWindow.__init__(self, master)
-        self.setWindowTitle("Media Player")
-
-        # Create a basic vlc instance
-        self.instance = vlc.Instance()
-
-        self.media = None
-
-        # Create an empty vlc media player
-        self.mediaplayer = self.instance.media_player_new()
-
-        self.create_ui()
-        self.is_paused = False
-
-    def create_ui(self):
-        """Set up the user interface, signals & slots
-        """
-        self.widget = QtWidgets.QWidget(self)
-        self.setCentralWidget(self.widget)
-
-        # In this widget, the video will be drawn
-        if platform.system() == "Darwin":  # for MacOS
-            self.videoframe = QtWidgets.QMacCocoaViewContainer(0)
-        else:
-            self.videoframe = QtWidgets.QFrame()
-
-        self.palette = self.videoframe.palette()
-        self.palette.setColor(QtGui.QPalette.Window, QtGui.QColor(0, 0, 0))
-        self.videoframe.setPalette(self.palette)
-        self.videoframe.setAutoFillBackground(True)
-
-        self.positionslider = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
-        self.positionslider.setToolTip("Position")
-        self.positionslider.setMaximum(1000)
-        self.positionslider.sliderMoved.connect(self.set_position)
-        self.positionslider.sliderPressed.connect(self.set_position)
-
-        self.hbuttonbox = QtWidgets.QHBoxLayout()
-        self.playbutton = QtWidgets.QPushButton("Play")
-        self.hbuttonbox.addWidget(self.playbutton)
-        self.playbutton.clicked.connect(self.play_pause)
-
-        self.stopbutton = QtWidgets.QPushButton("Stop")
-        self.hbuttonbox.addWidget(self.stopbutton)
-        self.stopbutton.clicked.connect(self.stop)
-
-        self.hbuttonbox.addStretch(1)
-        self.volumeslider = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
-        self.volumeslider.setMaximum(100)
-        self.volumeslider.setValue(self.mediaplayer.audio_get_volume())
-        self.volumeslider.setToolTip("Volume")
-        self.hbuttonbox.addWidget(self.volumeslider)
-        self.volumeslider.valueChanged.connect(self.set_volume)
-
-        self.vboxlayout = QtWidgets.QVBoxLayout()
-        self.vboxlayout.addWidget(self.videoframe)
-        self.vboxlayout.addWidget(self.positionslider)
-        self.vboxlayout.addLayout(self.hbuttonbox)
-
-        self.widget.setLayout(self.vboxlayout)
-
-        menu_bar = self.menuBar()
-
-        # File menu
-        file_menu = menu_bar.addMenu("File")
-
-        # Add actions to file menu
-        open_action = QtWidgets.QAction("Load Video", self)
-        close_action = QtWidgets.QAction("Close App", self)
-        file_menu.addAction(open_action)
-        file_menu.addAction(close_action)
-
-        open_action.triggered.connect(self.open_file)
-        close_action.triggered.connect(sys.exit)
-
-        self.timer = QtCore.QTimer(self)
-        self.timer.setInterval(100)
-        self.timer.timeout.connect(self.update_ui)
-
-    def play_pause(self):
-        """Toggle play/pause status
-        """
-        if self.mediaplayer.is_playing():
-            self.mediaplayer.pause()
-            self.playbutton.setText("Play")
-            self.is_paused = True
-            self.timer.stop()
-        else:
-            if self.mediaplayer.play() == -1:
-                self.open_file()
-                return
-
-            self.mediaplayer.play()
-            self.playbutton.setText("Pause")
-            self.timer.start()
-            self.is_paused = False
-
-    def stop(self):
-        """Stop player
-        """
-        self.mediaplayer.stop()
-        self.playbutton.setText("Play")
-
-    def open_file(self):
-        """Open a media file in a MediaPlayer
-        """
-
-        dialog_txt = "Choose Media File"
-        filename = QtWidgets.QFileDialog.getOpenFileName(self, dialog_txt, os.path.expanduser('~'))
-        if not filename:
-            return
-
-        # getOpenFileName returns a tuple, so use only the actual file name
-        self.media = self.instance.media_new(filename[0])
-
-        # Put the media in the media player
-        self.mediaplayer.set_media(self.media)
-
-        # Parse the metadata of the file
-        self.media.parse()
-
-        # Set the title of the track as window title
-        self.setWindowTitle(self.media.get_meta(0))
-
-        # The media player has to be 'connected' to the QFrame (otherwise the
-        # video would be displayed in it's own window). This is platform
-        # specific, so we must give the ID of the QFrame (or similar object) to
-        # vlc. Different platforms have different functions for this
-        if platform.system() == "Linux":  # for Linux using the X Server
-            self.mediaplayer.set_xwindow(int(self.videoframe.winId()))
-        elif platform.system() == "Windows":  # for Windows
-            self.mediaplayer.set_hwnd(int(self.videoframe.winId()))
-        elif platform.system() == "Darwin":  # for MacOS
-            self.mediaplayer.set_nsobject(int(self.videoframe.winId()))
-
-        self.play_pause()
-
-    def set_volume(self, volume):
-        """Set the volume
-        """
-        self.mediaplayer.audio_set_volume(volume)
-
-    def set_position(self):
-        """Set the movie position according to the position slider.
-        """
-
-        # The vlc MediaPlayer needs a float value between 0 and 1, Qt uses
-        # integer variables, so you need a factor; the higher the factor, the
-        # more precise are the results (1000 should suffice).
-
-        # Set the media position to where the slider was dragged
-        self.timer.stop()
-        pos = self.positionslider.value()
-        self.mediaplayer.set_position(pos / 1000.0)
-        self.timer.start()
-
-    def update_ui(self):
-        """Updates the user interface"""
-
-        # Set the slider's position to its corresponding media position
-        # Note that the setValue function only takes values of type int,
-        # so we must first convert the corresponding media position.
-        media_pos = int(self.mediaplayer.get_position() * 1000)
-        self.positionslider.setValue(media_pos)
-
-        # No need to call this function if nothing is played
-        if not self.mediaplayer.is_playing():
-            self.timer.stop()
-
-            # After the video finished, the play button stills shows "Pause",
-            # which is not the desired behavior of a media player.
-            # This fixes that "bug".
-            if not self.is_paused:
-                self.stop()
-
-
-def main():
-    """Entry point for our simple vlc player
-    """
-    app = QtWidgets.QApplication(sys.argv)
-    player = Player()
-    player.show()
-    player.resize(640, 480)
-    sys.exit(app.exec_())
-
-
-if __name__ == "__main__":
-    main()

+ 3 - 13
notes

@@ -6,23 +6,14 @@ TODO:
 
 Bugs:
 
-* Voir le pbm avec les mimetypes
 * voir le bug avec is_subdir_of() lorsque c'est une rép réseau
-* gérer pbm de loks à l'indexation, ex:
-      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.
 
 Priorité 1:
 
-* mettre à jour l'explorer au fur et à mesure de l'indexation
-* permettre l'ajout de tags
-* faire une modale pour l'édition des metadonnées
-* afficher l'activité de l'indexation dans la barre de statut
-* Enregistrer les notes pour un morceau et s'assurer qu'elles ne soient pas perdues
 * maj les tables playlist et explorer quand les metas d'un fichier sont modifiées
-* permettre de reset les metas d'une piste à partir du fichier ou de remplacer directement les metas du fichier
-* vérifier que les metas éditées ne sont pas ecrasées par l'indexeur
+* (?) permettre de reset les metas d'une piste à partir du fichier ou de remplacer directement les metas du fichier
+* permettre de réordonner correctement les musiques
+* permettre un glisser-déposer de l'explorer vers la playlist
 
 Priorité 2:
 
@@ -33,7 +24,6 @@ Priorité 2:
 * faire un prompt premier lancement pour ajouter des dossiers de musique et créer une première séance
 
 
-
 Demandes mathilde:
 
 * Imprimer la séance

+ 150 - 26
ui/qt/main.ui

@@ -7,13 +7,13 @@
     <x>0</x>
     <y>0</y>
     <width>1029</width>
-    <height>783</height>
+    <height>784</height>
    </rect>
   </property>
   <property name="minimumSize">
    <size>
     <width>1029</width>
-    <height>618</height>
+    <height>784</height>
    </size>
   </property>
   <property name="font">
@@ -464,7 +464,7 @@
                </layout>
               </item>
               <item>
-               <layout class="QVBoxLayout" name="verticalLayout_5" stretch="0,0,0,0">
+               <layout class="QVBoxLayout" name="verticalLayout_5" stretch="0,0,0">
                 <property name="leftMargin">
                  <number>10</number>
                 </property>
@@ -1130,13 +1130,13 @@
                         <property name="minimumSize">
                          <size>
                           <width>218</width>
-                          <height>160</height>
+                          <height>120</height>
                          </size>
                         </property>
                         <property name="maximumSize">
                          <size>
                           <width>16777215</width>
-                          <height>160</height>
+                          <height>120</height>
                          </size>
                         </property>
                         <property name="cursor" stdset="0">
@@ -1170,7 +1170,13 @@
                   <property name="minimumSize">
                    <size>
                     <width>220</width>
-                    <height>0</height>
+                    <height>38</height>
+                   </size>
+                  </property>
+                  <property name="maximumSize">
+                   <size>
+                    <width>16777215</width>
+                    <height>38</height>
                    </size>
                   </property>
                   <property name="text">
@@ -1196,35 +1202,21 @@
                   <property name="minimumSize">
                    <size>
                     <width>220</width>
-                    <height>0</height>
+                    <height>38</height>
                    </size>
                   </property>
-                  <property name="text">
-                   <string>  Ajouter à la playlist</string>
-                  </property>
-                  <property name="icon">
-                   <iconset resource="rsc.qrc">
-                    <normaloff>:/img/rsc/double-right-arrows-symbol.png</normaloff>:/img/rsc/double-right-arrows-symbol.png</iconset>
-                  </property>
-                 </widget>
-                </item>
-                <item>
-                 <widget class="QPushButton" name="explorerRemoveFromPlaylist">
-                  <property name="enabled">
-                   <bool>false</bool>
-                  </property>
-                  <property name="minimumSize">
+                  <property name="maximumSize">
                    <size>
-                    <width>220</width>
-                    <height>0</height>
+                    <width>16777215</width>
+                    <height>38</height>
                    </size>
                   </property>
                   <property name="text">
-                   <string>  Retirer de la playlist</string>
+                   <string>  Ajouter à la playlist</string>
                   </property>
                   <property name="icon">
                    <iconset resource="rsc.qrc">
-                    <normaloff>:/img/rsc/double-left-arrows-symbol.png</normaloff>:/img/rsc/double-left-arrows-symbol.png</iconset>
+                    <normaloff>:/img/rsc/plus.png</normaloff>:/img/rsc/plus.png</iconset>
                   </property>
                  </widget>
                 </item>
@@ -1353,6 +1345,138 @@
                   </column>
                  </widget>
                 </item>
+                <item>
+                 <layout class="QHBoxLayout" name="horizontalLayout_22">
+                  <item>
+                   <widget class="QToolButton" name="btnPlaylistMoveToTop">
+                    <property name="minimumSize">
+                     <size>
+                      <width>28</width>
+                      <height>28</height>
+                     </size>
+                    </property>
+                    <property name="maximumSize">
+                     <size>
+                      <width>28</width>
+                      <height>28</height>
+                     </size>
+                    </property>
+                    <property name="text">
+                     <string>...</string>
+                    </property>
+                    <property name="icon">
+                     <iconset resource="rsc.qrc">
+                      <normaloff>:/img/rsc/double-up-arrow.png</normaloff>:/img/rsc/double-up-arrow.png</iconset>
+                    </property>
+                   </widget>
+                  </item>
+                  <item>
+                   <widget class="QToolButton" name="btnPlaylistMoveUp">
+                    <property name="minimumSize">
+                     <size>
+                      <width>28</width>
+                      <height>28</height>
+                     </size>
+                    </property>
+                    <property name="maximumSize">
+                     <size>
+                      <width>28</width>
+                      <height>28</height>
+                     </size>
+                    </property>
+                    <property name="text">
+                     <string>...</string>
+                    </property>
+                    <property name="icon">
+                     <iconset resource="rsc.qrc">
+                      <normaloff>:/img/rsc/arrow-up.png</normaloff>:/img/rsc/arrow-up.png</iconset>
+                    </property>
+                   </widget>
+                  </item>
+                  <item>
+                   <widget class="QToolButton" name="btnPlaylistMoveToBelow">
+                    <property name="minimumSize">
+                     <size>
+                      <width>28</width>
+                      <height>28</height>
+                     </size>
+                    </property>
+                    <property name="maximumSize">
+                     <size>
+                      <width>28</width>
+                      <height>288</height>
+                     </size>
+                    </property>
+                    <property name="text">
+                     <string>...</string>
+                    </property>
+                    <property name="icon">
+                     <iconset resource="rsc.qrc">
+                      <normaloff>:/img/rsc/arrow-down.png</normaloff>:/img/rsc/arrow-down.png</iconset>
+                    </property>
+                   </widget>
+                  </item>
+                  <item>
+                   <widget class="QToolButton" name="btnPlaylistMoveToBottom">
+                    <property name="minimumSize">
+                     <size>
+                      <width>28</width>
+                      <height>28</height>
+                     </size>
+                    </property>
+                    <property name="maximumSize">
+                     <size>
+                      <width>28</width>
+                      <height>28</height>
+                     </size>
+                    </property>
+                    <property name="text">
+                     <string>...</string>
+                    </property>
+                    <property name="icon">
+                     <iconset resource="rsc.qrc">
+                      <normaloff>:/img/rsc/double-below-arrow.png</normaloff>:/img/rsc/double-below-arrow.png</iconset>
+                    </property>
+                   </widget>
+                  </item>
+                  <item>
+                   <spacer name="horizontalSpacer_7">
+                    <property name="orientation">
+                     <enum>Qt::Horizontal</enum>
+                    </property>
+                    <property name="sizeHint" stdset="0">
+                     <size>
+                      <width>40</width>
+                      <height>20</height>
+                     </size>
+                    </property>
+                   </spacer>
+                  </item>
+                  <item>
+                   <widget class="QToolButton" name="btnPlaylistRemove">
+                    <property name="minimumSize">
+                     <size>
+                      <width>28</width>
+                      <height>28</height>
+                     </size>
+                    </property>
+                    <property name="maximumSize">
+                     <size>
+                      <width>28</width>
+                      <height>28</height>
+                     </size>
+                    </property>
+                    <property name="text">
+                     <string>...</string>
+                    </property>
+                    <property name="icon">
+                     <iconset resource="rsc.qrc">
+                      <normaloff>:/img/rsc/trash.png</normaloff>:/img/rsc/trash.png</iconset>
+                    </property>
+                   </widget>
+                  </item>
+                 </layout>
+                </item>
                </layout>
               </item>
              </layout>

+ 5 - 0
ui/qt/rsc.qrc

@@ -1,5 +1,10 @@
 <RCC>
   <qresource prefix="/img">
+    <file>rsc/trash.png</file>
+    <file>rsc/double-below-arrow.png</file>
+    <file>rsc/double-up-arrow.png</file>
+    <file>rsc/arrow-down.png</file>
+    <file>rsc/arrow-up.png</file>
     <file>rsc/unknown.png</file>
     <file>rsc/valid.png</file>
     <file>rsc/invalid.png</file>

BIN
ui/qt/rsc/arrow-down.png


BIN
ui/qt/rsc/arrow-up.png


BIN
ui/qt/rsc/double-below-arrow.png


BIN
ui/qt/rsc/double-up-arrow.png


BIN
ui/qt/rsc/trash.png


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 661 - 1084
ui/qt/rsc_rc.py


Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä