openlp-core team mailing list archive
-
openlp-core team
-
Mailing list archive
-
Message #26464
[Merge] lp:~tomasgroth/openlp/bugfixes17 into lp:openlp
Tomas Groth has proposed merging lp:~tomasgroth/openlp/bugfixes17 into lp:openlp.
Requested reviews:
OpenLP Core (openlp-core)
Related bugs:
Bug #1413324 in OpenLP: "Going live on songs too quickly causes hang"
https://bugs.launchpad.net/openlp/+bug/1413324
Bug #1431476 in OpenLP: "Exception when playing a mpg file with webkit"
https://bugs.launchpad.net/openlp/+bug/1431476
Bug #1431478 in OpenLP: "Size of media slider should not change"
https://bugs.launchpad.net/openlp/+bug/1431478
Bug #1432418 in OpenLP: "delete PowerPoint presentation before removing from service"
https://bugs.launchpad.net/openlp/+bug/1432418
Bug #1433245 in OpenLP: "Error message when start playing a video with vlc"
https://bugs.launchpad.net/openlp/+bug/1433245
For more details, see:
https://code.launchpad.net/~tomasgroth/openlp/bugfixes17/+merge/253448
Insert timeout on acquiring lock in slidecontroller to avoid hang. Fixes bug 1413324.
Run XInitThreads when using VLC to make it work correctly. Fixes bug 1433245.
Disable the stop button in the slidecontroller mediaplayer buttons instead of hiding it to stop the position and audio slider resizing. Fixes bug 1431478.
Fixed a webkit player exception. Fixes bug 1431476.
Fix crash if presentation file in the mediamanger was removed bewteen sessions. Fixes bug 1432418.
Updated the list of extensions supported by VLC.
--
Your team OpenLP Core is requested to review the proposed merge of lp:~tomasgroth/openlp/bugfixes17 into lp:openlp.
=== modified file 'openlp/core/ui/media/mediacontroller.py'
--- openlp/core/ui/media/mediacontroller.py 2015-02-18 21:32:42 +0000
+++ openlp/core/ui/media/mediacontroller.py 2015-03-18 22:13:54 +0000
@@ -589,7 +589,7 @@
else:
controller.mediabar.actions['playbackPlay'].setVisible(False)
controller.mediabar.actions['playbackPause'].setVisible(True)
- controller.mediabar.actions['playbackStop'].setVisible(True)
+ controller.mediabar.actions['playbackStop'].setDisabled(False)
if controller.is_live:
if controller.hide_menu.defaultAction().isChecked() and not controller.media_info.is_background:
controller.hide_menu.defaultAction().trigger()
@@ -619,7 +619,7 @@
display = self._define_display(controller)
self.current_media_players[controller.controller_type].pause(display)
controller.mediabar.actions['playbackPlay'].setVisible(True)
- controller.mediabar.actions['playbackStop'].setVisible(True)
+ controller.mediabar.actions['playbackStop'].setDisabled(False)
controller.mediabar.actions['playbackPause'].setVisible(False)
def media_stop_msg(self, msg):
@@ -645,7 +645,7 @@
self.current_media_players[controller.controller_type].set_visible(display, False)
controller.seek_slider.setSliderPosition(0)
controller.mediabar.actions['playbackPlay'].setVisible(True)
- controller.mediabar.actions['playbackStop'].setVisible(False)
+ controller.mediabar.actions['playbackStop'].setDisabled(True)
controller.mediabar.actions['playbackPause'].setVisible(False)
def media_volume_msg(self, msg):
=== modified file 'openlp/core/ui/media/vlcplayer.py'
--- openlp/core/ui/media/vlcplayer.py 2015-01-18 13:39:21 +0000
+++ openlp/core/ui/media/vlcplayer.py 2015-03-18 22:13:54 +0000
@@ -27,10 +27,11 @@
import logging
import os
import threading
+import sys
from PyQt4 import QtGui
-from openlp.core.common import Settings, is_win, is_macosx
+from openlp.core.common import Settings, is_win, is_macosx, is_linux
from openlp.core.lib import translate
from openlp.core.ui.media import MediaState, MediaType
from openlp.core.ui.media.mediaplayer import MediaPlayer
@@ -62,36 +63,30 @@
if LooseVersion(VERSION.split()[0]) < LooseVersion('1.1.0'):
VLC_AVAILABLE = False
log.debug('VLC could not be loaded, because the vlc version is too old: %s' % VERSION)
-
-AUDIO_EXT = ['*.mp3', '*.wav', '*.wma', '*.ogg']
-
-VIDEO_EXT = [
- '*.3gp',
- '*.asf', '*.wmv',
- '*.au',
- '*.avi',
- '*.divx',
- '*.flv',
- '*.mov',
- '*.mp4', '*.m4v',
- '*.ogm', '*.ogv',
- '*.mkv', '*.mka',
- '*.ts', '*.mpg',
- '*.mpg', '*.mp2',
- '*.nsc',
- '*.nsv',
- '*.nut',
- '*.ra', '*.ram', '*.rm', '*.rv', '*.rmbv',
- '*.a52', '*.dts', '*.aac', '*.flac', '*.dv', '*.vid',
- '*.tta', '*.tac',
- '*.ty',
- '*.dts',
- '*.xa',
- '*.iso',
- '*.vob',
- '*.webm',
- '*.xvid'
-]
+ # On linux we need to initialise X threads, but not when running tests.
+ if VLC_AVAILABLE and is_linux() and 'nose' not in sys.argv[0]:
+ import ctypes
+ try:
+ x11 = ctypes.cdll.LoadLibrary('libX11.so')
+ x11.XInitThreads()
+ except:
+ log.exception('Failed to run XInitThreads(), VLC might not work properly!')
+
+# Audio and video extensions copied from 'include/vlc_interface.h' from vlc 2.2.0 source
+AUDIO_EXT = ['*.3ga', '*.669', '*.a52', '*.aac', '*.ac3', '*.adt', '*.adts', '*.aif', '*.aifc', '*.aiff', '*.amr',
+ '*.aob', '*.ape', '*.awb', '*.caf', '*.dts', '*.flac', '*.it', '*.kar', '*.m4a', '*.m4b', '*.m4p', '*.m5p',
+ '*.mid', '*.mka', '*.mlp', '*.mod', '*.mpa', '*.mp1', '*.mp2', '*.mp3', '*.mpc', '*.mpga', '*.mus',
+ '*.oga', '*.ogg', '*.oma', '*.opus', '*.qcp', '*.ra', '*.rmi', '*.s3m', '*.sid', '*.spx', '*.thd', '*.tta',
+ '*.voc', '*.vqf', '*.w64', '*.wav', '*.wma', '*.wv', '*.xa', '*.xm']
+
+VIDEO_EXT = ['*.3g2', '*.3gp', '*.3gp2', '*.3gpp', '*.amv', '*.asf', '*.avi', '*.bik', '*.divx', '*.drc', '*.dv',
+ '*.f4v', '*.flv', '*.gvi', '*.gxf', '*.iso', '*.m1v', '*.m2v', '*.m2t', '*.m2ts', '*.m4v', '*.mkv',
+ '*.mov', '*.mp2', '*.mp2v', '*.mp4', '*.mp4v', '*.mpe', '*.mpeg', '*.mpeg1', '*.mpeg2', '*.mpeg4', '*.mpg',
+ '*.mpv2', '*.mts', '*.mtv', '*.mxf', '*.mxg', '*.nsv', '*.nuv', '*.ogg', '*.ogm', '*.ogv', '*.ogx', '*.ps',
+ '*.rec', '*.rm', '*.rmvb', '*.rpl', '*.thp', '*.tod', '*.ts', '*.tts', '*.txd', '*.vob', '*.vro', '*.webm',
+ '*.wm', '*.wmv', '*.wtv', '*.xesc',
+ # These extensions was not in the official list, added manually.
+ '*.nut', '*.rv', '*.xvid']
class VlcPlayer(MediaPlayer):
=== modified file 'openlp/core/ui/media/webkitplayer.py'
--- openlp/core/ui/media/webkitplayer.py 2015-01-26 21:18:23 +0000
+++ openlp/core/ui/media/webkitplayer.py 2015-03-18 22:13:54 +0000
@@ -375,7 +375,7 @@
# check if conversion was ok and value is not 'NaN'
if length and length != float('inf'):
length = int(length * 1000)
- if current_time:
+ if current_time and length:
controller.media_info.length = length
controller.seek_slider.setMaximum(length)
if not controller.seek_slider.isSliderDown():
=== modified file 'openlp/core/ui/slidecontroller.py'
--- openlp/core/ui/slidecontroller.py 2015-03-09 20:57:39 +0000
+++ openlp/core/ui/slidecontroller.py 2015-03-18 22:13:54 +0000
@@ -1069,8 +1069,13 @@
:param start:
"""
# Only one thread should be in here at the time. If already locked just skip, since the update will be
- # done by the thread holding the lock. If it is a "start" slide, we must wait for the lock.
- if not self.slide_selected_lock.acquire(start):
+ # done by the thread holding the lock. If it is a "start" slide, we must wait for the lock, but only for 0.2
+ # seconds, since we don't want to cause a deadlock
+ timeout = 0.2 if start else -1
+ if not self.slide_selected_lock.acquire(start, timeout):
+ if start:
+ self.log_debug('Could not get lock in slide_selected after waiting %f, skip to avoid deadlock.'
+ % timeout)
return
row = self.preview_widget.current_slide_number()
self.selected_row = 0
=== modified file 'openlp/plugins/presentations/lib/mediaitem.py'
--- openlp/plugins/presentations/lib/mediaitem.py 2015-03-10 22:00:32 +0000
+++ openlp/plugins/presentations/lib/mediaitem.py 2015-03-18 22:13:54 +0000
@@ -245,7 +245,8 @@
doc = self.controllers[cidx].add_document(filepath)
if clean_for_update:
thumb_path = doc.get_thumbnail_path(1, True)
- if not thumb_path or os.path.getmtime(thumb_path) < os.path.getmtime(filepath):
+ if not thumb_path or not os.path.exists(filepath) or os.path.getmtime(
+ thumb_path) < os.path.getmtime(filepath):
doc.presentation_deleted()
else:
doc.presentation_deleted()
=== modified file 'tests/functional/openlp_plugins/presentations/test_mediaitem.py'
--- tests/functional/openlp_plugins/presentations/test_mediaitem.py 2015-03-10 23:46:37 +0000
+++ tests/functional/openlp_plugins/presentations/test_mediaitem.py 2015-03-18 22:13:54 +0000
@@ -87,7 +87,7 @@
def clean_up_thumbnails_test(self):
"""
- Test that the clean_up_thumbnails method works as expected.
+ Test that the clean_up_thumbnails method works as expected when files exists.
"""
# GIVEN: A mocked controller, and mocked os.path.getmtime
mocked_controller = MagicMock()
@@ -98,8 +98,10 @@
'Mocked': mocked_controller
}
presentation_file = 'file.tmp'
- with patch('openlp.plugins.presentations.lib.mediaitem.os.path.getmtime') as mocked_getmtime:
+ with patch('openlp.plugins.presentations.lib.mediaitem.os.path.getmtime') as mocked_getmtime, \
+ patch('openlp.plugins.presentations.lib.mediaitem.os.path.exists') as mocked_exists:
mocked_getmtime.side_effect = [100, 200]
+ mocked_exists.return_value = True
# WHEN: calling clean_up_thumbnails
self.media_item.clean_up_thumbnails(presentation_file, True)
@@ -107,3 +109,25 @@
# THEN: doc.presentation_deleted should have been called since the thumbnails mtime will be greater than
# the presentation_file's mtime.
mocked_doc.assert_has_calls([call.get_thumbnail_path(1, True), call.presentation_deleted()], True)
+
+ def clean_up_thumbnails_missing_file_test(self):
+ """
+ Test that the clean_up_thumbnails method works as expected when file is missing.
+ """
+ # GIVEN: A mocked controller, and mocked os.path.exists
+ mocked_controller = MagicMock()
+ mocked_doc = MagicMock()
+ mocked_controller.add_document.return_value = mocked_doc
+ mocked_controller.supports = ['tmp']
+ self.media_item.controllers = {
+ 'Mocked': mocked_controller
+ }
+ presentation_file = 'file.tmp'
+ with patch('openlp.plugins.presentations.lib.mediaitem.os.path.exists') as mocked_exists:
+ mocked_exists.return_value = False
+
+ # WHEN: calling clean_up_thumbnails
+ self.media_item.clean_up_thumbnails(presentation_file, True)
+
+ # THEN: doc.presentation_deleted should have been called since the presentation file did not exists.
+ mocked_doc.assert_has_calls([call.get_thumbnail_path(1, True), call.presentation_deleted()], True)
References