← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~tomasgroth/openlp/dvd-fixes into lp:openlp

 

Tomas Groth has proposed merging lp:~tomasgroth/openlp/dvd-fixes into lp:openlp.

Requested reviews:
  OpenLP Core (openlp-core)

For more details, see:
https://code.launchpad.net/~tomasgroth/openlp/dvd-fixes/+merge/233812

Fixes for DVD
-- 
https://code.launchpad.net/~tomasgroth/openlp/dvd-fixes/+merge/233812
Your team OpenLP Core is requested to review the proposed merge of lp:~tomasgroth/openlp/dvd-fixes into lp:openlp.
=== modified file 'openlp/plugins/media/forms/mediaclipselectorform.py'
--- openlp/plugins/media/forms/mediaclipselectorform.py	2014-09-02 20:15:18 +0000
+++ openlp/plugins/media/forms/mediaclipselectorform.py	2014-09-08 21:02:25 +0000
@@ -28,31 +28,29 @@
 ###############################################################################
 
 import os
-if os.name == 'nt':
-    from win32com.client import Dispatch
-    import string
-import sys
-
-if sys.platform.startswith('linux'):
-    import dbus
 import logging
 import re
 from time import sleep
 from datetime import datetime
 
-
 from PyQt4 import QtCore, QtGui
 
-from openlp.core.common import translate
+from openlp.core.common import translate, is_win, is_linux, is_macosx, RegistryProperties
 from openlp.plugins.media.forms.mediaclipselectordialog import Ui_MediaClipSelector
 from openlp.core.lib.ui import critical_error_message_box
-from openlp.core.ui.media import format_milliseconds
+
+if is_win():
+    from win32com.client import Dispatch
+
+if is_linux():
+    import dbus
+
 try:
     from openlp.core.ui.media.vendor import vlc
 except (ImportError, NameError, NotImplementedError):
     pass
 except OSError as e:
-    if sys.platform.startswith('win'):
+    if is_win():
         if not isinstance(e, WindowsError) and e.winerror != 126:
             raise
     else:
@@ -61,7 +59,7 @@
 log = logging.getLogger(__name__)
 
 
-class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector):
+class MediaClipSelectorForm(QtGui.QDialog, Ui_MediaClipSelector, RegistryProperties):
     """
     Class to manage the clip selection
     """
@@ -144,9 +142,9 @@
         # You have to give the id of the QFrame (or similar object)
         # to vlc, different platforms have different functions for this.
         win_id = int(self.preview_frame.winId())
-        if sys.platform == "win32":
+        if is_win():
             self.vlc_media_player.set_hwnd(win_id)
-        elif sys.platform == "darwin":
+        elif is_macosx():
             # We have to use 'set_nsobject' since Qt4 on OSX uses Cocoa
             # framework and not the old Carbon.
             self.vlc_media_player.set_nsobject(win_id)
@@ -190,7 +188,7 @@
         self.audio_cd = True
         self.titles_combo_box.setDisabled(False)
         self.titles_combo_box.setCurrentIndex(0)
-        self.on_title_combo_box_currentIndexChanged(0)
+        self.on_titles_combo_box_currentIndexChanged(0)
 
         return True
 
@@ -203,18 +201,21 @@
         """
         log.debug('on_load_disc_button_clicked')
         self.disable_all()
+        self.application.set_busy_cursor()
         path = self.media_path_combobox.currentText()
         # Check if given path is non-empty and exists before starting VLC
         if not path:
             log.debug('no given path')
             critical_error_message_box(message=translate('MediaPlugin.MediaClipSelectorForm', 'No path was given'))
             self.toggle_disable_load_media(False)
+            self.application.set_normal_cursor()
             return
         if not os.path.exists(path):
             log.debug('Given path does not exists')
             critical_error_message_box(message=translate('MediaPlugin.MediaClipSelectorForm',
                                                          'Given path does not exists'))
             self.toggle_disable_load_media(False)
+            self.application.set_normal_cursor()
             return
         # VLC behaves a bit differently on windows and linux when loading, which creates problems when trying to
         # detect if we're dealing with a DVD or CD, so we use different loading approaches depending on the OS.
@@ -231,6 +232,7 @@
             critical_error_message_box(message=translate('MediaPlugin.MediaClipSelectorForm',
                                                          'An error happened during initialization of VLC player'))
             self.toggle_disable_load_media(False)
+            self.application.set_normal_cursor()
             return
         # put the media in the media player
         self.vlc_media_player.set_media(self.vlc_media)
@@ -241,6 +243,8 @@
             critical_error_message_box(message=translate('MediaPlugin.MediaClipSelectorForm',
                                                          'VLC player failed playing the media'))
             self.toggle_disable_load_media(False)
+            self.application.set_normal_cursor()
+            self.vlc_media_player.audio_set_mute(False)
             return
         self.vlc_media_player.audio_set_mute(True)
         if not self.media_state_wait(vlc.State.Playing):
@@ -249,23 +253,32 @@
                 critical_error_message_box(message=translate('MediaPlugin.MediaClipSelectorForm',
                                                              'VLC player failed playing the media'))
                 self.toggle_disable_load_media(False)
+                self.application.set_normal_cursor()
+                self.vlc_media_player.audio_set_mute(False)
                 return
-        self.vlc_media_player.audio_set_mute(True)
+        # pause
+        self.vlc_media_player.set_time(0)
+        self.vlc_media_player.set_pause(1)
+        self.media_state_wait(vlc.State.Paused)
+        self.toggle_disable_load_media(False)
+        self.application.set_normal_cursor()
+        self.vlc_media_player.audio_set_mute(False)
         if not self.audio_cd:
+            # Temporarily disable signals
+            self.blockSignals(True)
             # Get titles, insert in combobox
             titles = self.vlc_media_player.video_get_title_description()
             self.titles_combo_box.clear()
             for title in titles:
                 self.titles_combo_box.addItem(title[1].decode(), title[0])
+            # Re-enable signals
+            self.blockSignals(False)
             # Main title is usually title #1
             if len(titles) > 1:
                 self.titles_combo_box.setCurrentIndex(1)
-            else:
-                self.titles_combo_box.setCurrentIndex(0)
             # Enable audio track combobox if anything is in it
             if len(titles) > 0:
                 self.titles_combo_box.setDisabled(False)
-        self.toggle_disable_load_media(False)
         log.debug('load_disc_button end - vlc_media_player state: %s' % self.vlc_media_player.get_state())
 
     @QtCore.pyqtSlot(bool)
@@ -378,6 +391,7 @@
         if not self.vlc_media_player:
             log.error('vlc_media_player was None')
             return
+        self.application.set_busy_cursor()
         if self.audio_cd:
             self.vlc_media = self.audio_cd_tracks.item_at_index(index)
             self.vlc_media_player.set_media(self.vlc_media)
@@ -385,14 +399,14 @@
             self.vlc_media_player.play()
             if not self.media_state_wait(vlc.State.Playing):
                 log.error('Could not start playing audio cd, needed to get track info')
+                self.application.set_normal_cursor()
                 return
             self.vlc_media_player.audio_set_mute(True)
-            # Sleep 1 second to make sure VLC has the needed metadata
-            sleep(1)
             # pause
             self.vlc_media_player.set_time(0)
             self.vlc_media_player.set_pause(1)
             self.vlc_media_player.audio_set_mute(False)
+            self.application.set_normal_cursor()
             self.toggle_disable_player(False)
         else:
             self.vlc_media_player.set_title(index)
@@ -400,13 +414,13 @@
             self.vlc_media_player.play()
             if not self.media_state_wait(vlc.State.Playing):
                 log.error('Could not start playing dvd, needed to get track info')
+                self.application.set_normal_cursor()
                 return
             self.vlc_media_player.audio_set_mute(True)
-            # Sleep 1 second to make sure VLC has the needed metadata
-            sleep(1)
-            self.vlc_media_player.set_time(0)
-            # Get audio tracks, insert in combobox
+            # Get audio tracks
             audio_tracks = self.vlc_media_player.audio_get_track_description()
+            log.debug('number of audio tracks: %d' % len(audio_tracks))
+            # Clear the audio track combobox, insert new tracks
             self.audio_tracks_combobox.clear()
             for audio_track in audio_tracks:
                 self.audio_tracks_combobox.addItem(audio_track[1].decode(), audio_track[0])
@@ -447,6 +461,7 @@
             self.vlc_media_player.set_pause(1)
             loop_count += 1
         log.debug('titles_combo_box end - vlc_media_player state: %s' % self.vlc_media_player.get_state())
+        self.application.set_normal_cursor()
 
     @QtCore.pyqtSlot(int)
     def on_audio_tracks_combobox_currentIndexChanged(self, index):
@@ -535,7 +550,7 @@
         """
         Saves the current media and trackinfo as a clip to the mediamanager
         """
-        log.debug('in on_save_button_clicked')
+        log.debug('in MediaClipSelectorForm.accept')
         start_time = self.start_position_edit.time()
         start_time_ms = start_time.hour() * 60 * 60 * 1000 + \
             start_time.minute() * 60 * 1000 + \
@@ -550,10 +565,23 @@
         path = self.media_path_combobox.currentText()
         optical = ''
         if self.audio_cd:
+            # Check for load problems
+            if start_time_ms is None or end_time_ms is None or title is None:
+                critical_error_message_box(translate('MediaPlugin.MediaClipSelectorForm', 'CD not loaded correctly'),
+                                           translate('MediaPlugin.MediaClipSelectorForm',
+                                                     'The CD was not loaded correctly, please re-load and try again.'))
+                return
             optical = 'optical:%d:-1:-1:%d:%d:' % (title, start_time_ms, end_time_ms)
         else:
             audio_track = self.audio_tracks_combobox.itemData(self.audio_tracks_combobox.currentIndex())
             subtitle_track = self.subtitle_tracks_combobox.itemData(self.subtitle_tracks_combobox.currentIndex())
+            # Check for load problems
+            if start_time_ms is None or end_time_ms is None or title is None or audio_track is None\
+                    or subtitle_track is None:
+                critical_error_message_box(translate('MediaPlugin.MediaClipSelectorForm', 'DVD not loaded correctly'),
+                                           translate('MediaPlugin.MediaClipSelectorForm',
+                                                     'The DVD was not loaded correctly, please re-load and try again.'))
+                return
             optical = 'optical:%d:%d:%d:%d:%d:' % (title, audio_track, subtitle_track, start_time_ms, end_time_ms)
         # Ask for an alternative name for the mediaclip
         while True:
@@ -595,7 +623,7 @@
         while media_state != self.vlc_media_player.get_state():
             if self.vlc_media_player.get_state() == vlc.State.Error:
                 return False
-            if (datetime.now() - start).seconds > 30:
+            if (datetime.now() - start).seconds > 15:
                 return False
         return True
 
@@ -606,7 +634,7 @@
         """
         # Clear list first
         self.media_path_combobox.clear()
-        if os.name == 'nt':
+        if is_win():
             # use win api to find optical drives
             fso = Dispatch('scripting.filesystemobject')
             for drive in fso.Drives:
@@ -614,7 +642,7 @@
                 # if type is 4, it is a cd-rom drive
                 if drive.DriveType == 4:
                     self.media_path_combobox.addItem('%s:\\' % drive.DriveLetter)
-        elif sys.platform.startswith('linux'):
+        elif is_linux():
             # Get disc devices from dbus and find the ones that are optical
             bus = dbus.SystemBus()
             try:
@@ -646,7 +674,7 @@
                                     if chr(c) != '\x00':
                                         block_file += chr(c)
                                 self.media_path_combobox.addItem(block_file)
-        elif sys.platform.startswith('darwin'):
+        elif is_macosx():
             # Look for DVD folders in devices to find optical devices
             volumes = os.listdir('/Volumes')
             candidates = list()

=== modified file 'tests/interfaces/openlp_plugins/media/__init__.py'
--- tests/interfaces/openlp_plugins/media/__init__.py	2014-03-20 21:52:53 +0000
+++ tests/interfaces/openlp_plugins/media/__init__.py	2014-09-08 21:02:25 +0000
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection                                      #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2014 Raoul Snyman                                        #
+# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan      #
+# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub,      #
+# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer.   #
+# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru,          #
+# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith,             #
+# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock,              #
+# Frode Woldsund, Martin Zibricky, Patrick Zimmermann                         #
+# --------------------------------------------------------------------------- #
+# 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; version 2 of the License.                              #
+#                                                                             #
+# 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., 59  #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
+###############################################################################

=== added file 'tests/interfaces/openlp_plugins/media/forms/__init__.py'
--- tests/interfaces/openlp_plugins/media/forms/__init__.py	1970-01-01 00:00:00 +0000
+++ tests/interfaces/openlp_plugins/media/forms/__init__.py	2014-09-08 21:02:25 +0000
@@ -0,0 +1,28 @@
+# -*- coding: utf-8 -*-
+# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
+
+###############################################################################
+# OpenLP - Open Source Lyrics Projection                                      #
+# --------------------------------------------------------------------------- #
+# Copyright (c) 2008-2014 Raoul Snyman                                        #
+# Portions copyright (c) 2008-2014 Tim Bentley, Gerald Britton, Jonathan      #
+# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub,      #
+# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer.   #
+# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru,          #
+# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith,             #
+# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock,              #
+# Frode Woldsund, Martin Zibricky, Patrick Zimmermann                         #
+# --------------------------------------------------------------------------- #
+# 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; version 2 of the License.                              #
+#                                                                             #
+# 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., 59  #
+# Temple Place, Suite 330, Boston, MA 02111-1307 USA                          #
+###############################################################################

=== modified file 'tests/interfaces/openlp_plugins/media/forms/test_mediaclipselectorform.py'
--- tests/interfaces/openlp_plugins/media/forms/test_mediaclipselectorform.py	2014-08-20 23:35:24 +0000
+++ tests/interfaces/openlp_plugins/media/forms/test_mediaclipselectorform.py	2014-09-08 21:02:25 +0000
@@ -60,6 +60,7 @@
         # Mock VLC so we don't actually use it
         self.vlc_patcher = patch('openlp.plugins.media.forms.mediaclipselectorform.vlc')
         self.vlc_patcher.start()
+        Registry().register('application', self.app)
         # Mock the media item
         self.mock_media_item = MagicMock()
         # create form to test
@@ -67,6 +68,9 @@
         mock_media_state_wait = MagicMock()
         mock_media_state_wait.return_value = True
         self.form.media_state_wait = mock_media_state_wait
+        self.form.application.set_busy_cursor = MagicMock()
+        self.form.application.set_normal_cursor = MagicMock()
+        self.form.find_optical_devices = MagicMock()
 
     def tearDown(self):
         """
@@ -155,3 +159,21 @@
             self.form.audio_tracks_combobox.itemData.assert_any_call(0)
             self.form.audio_tracks_combobox.itemData.assert_any_call(1)
             self.form.subtitle_tracks_combobox.itemData.assert_any_call(0)
+
+    def click_save_button_test(self):
+        """
+        Test that the correct function is called when save is clicked, and that it behaves as expected.
+        """
+        # GIVEN: Mocked methods.
+        with patch('openlp.plugins.media.forms.mediaclipselectorform.critical_error_message_box') as \
+                mocked_critical_error_message_box,\
+                patch('PyQt4.QtGui.QDialog.exec_') as mocked_exec:
+            self.form.exec_()
+
+            # WHEN: The save button is clicked with a NoneType in start_time_ms or end_time_ms
+            self.form.accept()
+
+            # THEN: we should get an error message
+            mocked_critical_error_message_box.assert_called_with('DVD not loaded correctly',
+                                                                 'The DVD was not loaded correctly, '
+                                                                 'please re-load and try again.')


References