forked from openlp/openlp
Merge branch 'media_sept_19' into 'master'
Media sept 19 See merge request openlp/openlp!21
This commit is contained in:
commit
cdba0e9235
@ -33,7 +33,6 @@ from openlp.core.common import Singleton, is_macosx, is_win
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
from openlp.core.common.settings import Settings
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -385,6 +384,7 @@ class UiStrings(metaclass=Singleton):
|
||||
self.Import = translate('OpenLP.Ui', 'Import')
|
||||
self.LayoutStyle = translate('OpenLP.Ui', 'Layout style:')
|
||||
self.Live = translate('OpenLP.Ui', 'Live')
|
||||
self.LiveStream = translate('OpenLP.Ui', 'Live Stream')
|
||||
self.LiveBGError = translate('OpenLP.Ui', 'Live Background Error')
|
||||
self.LiveToolbar = translate('OpenLP.Ui', 'Live Toolbar')
|
||||
self.Load = translate('OpenLP.Ui', 'Load')
|
||||
|
@ -41,7 +41,6 @@ from openlp.core.widgets.edits import SearchEdit
|
||||
from openlp.core.widgets.toolbar import OpenLPToolbar
|
||||
from openlp.core.widgets.views import ListWidgetWithDnD
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -416,6 +415,8 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
||||
for index in range(self.list_view.count()):
|
||||
list_item = self.list_view.item(index)
|
||||
file_path = list_item.data(QtCore.Qt.UserRole)
|
||||
# This is added as start of OpenLP each time
|
||||
if file_path != UiStrings().LiveStream:
|
||||
file_paths.append(file_path)
|
||||
return file_paths
|
||||
|
||||
@ -497,7 +498,7 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
||||
translate('OpenLP.MediaManagerItem',
|
||||
'You must select one or more items to preview.'))
|
||||
else:
|
||||
log.debug('%s Preview requested' % self.plugin.name)
|
||||
log.debug('{plug} Preview requested'.format(plug=self.plugin.name))
|
||||
Registry().set_flag('has doubleclick added item to service', False)
|
||||
service_item = self.build_service_item()
|
||||
if service_item:
|
||||
@ -635,7 +636,6 @@ class MediaManagerItem(QtWidgets.QWidget, RegistryProperties):
|
||||
service_item.add_icon()
|
||||
if self.generate_slide_data(service_item, item=item, remote=remote, context=context):
|
||||
return service_item
|
||||
else:
|
||||
return None
|
||||
|
||||
def service_load(self, item):
|
||||
|
@ -54,16 +54,7 @@ TICK_TIME = 200
|
||||
|
||||
class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
"""
|
||||
The implementation of the Media Controller. The Media Controller adds an own class for every Player.
|
||||
Currently these are QtWebkit, Phonon and Vlc. display_controllers are an array of controllers keyed on the
|
||||
slidecontroller or plugin which built them.
|
||||
|
||||
ControllerType is the class containing the key values.
|
||||
|
||||
media_players are an array of media players keyed on player name.
|
||||
|
||||
current_media_players is an array of player instances keyed on ControllerType.
|
||||
|
||||
The implementation of the Media Controller which manages how media is played.
|
||||
"""
|
||||
|
||||
def setup(self):
|
||||
@ -100,14 +91,23 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
self.vlc_player = VlcPlayer(self)
|
||||
State().add_service('mediacontroller', 0)
|
||||
State().add_service('media_live', 0)
|
||||
if get_vlc() and pymediainfo_available:
|
||||
getvlc = get_vlc()
|
||||
if getvlc and pymediainfo_available:
|
||||
State().update_pre_conditions('mediacontroller', True)
|
||||
State().update_pre_conditions('media_live', True)
|
||||
else:
|
||||
if hasattr(self.main_window, 'splash') and self.main_window.splash.isVisible():
|
||||
self.main_window.splash.hide()
|
||||
State().missing_text('media_live', translate('OpenLP.SlideController',
|
||||
'VLC or pymediainfo are missing, so you are unable to play any media'))
|
||||
text_vlc = translate('OpenLP.MediaController',
|
||||
'The media integration library is missing (python - vlc is not installed)')
|
||||
text_info = translate('OpenLP.MediaController',
|
||||
'The media integration library is missing (python - pymediainfo is not installed)')
|
||||
if not getvlc and not pymediainfo_available:
|
||||
State().missing_text('media_live', "{text}\n{base}".format(text=text_vlc, base=text_info))
|
||||
if getvlc and not pymediainfo_available:
|
||||
State().missing_text('media_live', "{text}".format(text=text_info))
|
||||
if not getvlc and pymediainfo_available:
|
||||
State().missing_text('media_live', "{text}".format(text=text_vlc))
|
||||
return True
|
||||
|
||||
def bootstrap_post_set_up(self):
|
||||
@ -120,7 +120,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
self.setup_display(self.live_controller.display, False)
|
||||
except AttributeError:
|
||||
State().update_pre_conditions('media_live', False)
|
||||
State().missing_text('media_live', translate('OpenLP.SlideController',
|
||||
State().missing_text('media_live', translate('OpenLP.MediaController',
|
||||
'No Displays configure so Live Media has been disabled'))
|
||||
self.setup_display(self.preview_controller.preview_display, True)
|
||||
|
||||
@ -132,7 +132,6 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
"""
|
||||
if controller_type == DisplayControllerType.Live:
|
||||
return self.live_controller
|
||||
else:
|
||||
return self.preview_controller
|
||||
|
||||
def media_state_live(self):
|
||||
@ -271,10 +270,8 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
critical_error_message_box(translate('MediaPlugin.MediaItem', 'Unsupported File'),
|
||||
translate('MediaPlugin.MediaItem', 'Unsupported File'))
|
||||
return False
|
||||
log.debug('video media type: ' + str(controller.media_info.media_type))
|
||||
log.debug('video media type: {tpe} '.format(tpe=str(controller.media_info.media_type)))
|
||||
# dont care about actual theme, set a black background
|
||||
# if controller.is_live and not controller.media_info.is_background:
|
||||
# display.frame.runJavaScript('show_video("setBackBoard", null, null,"visible");')
|
||||
# now start playing - Preview is autoplay!
|
||||
autoplay = False
|
||||
if service_item.is_capable(ItemCapabilities.CanStream):
|
||||
@ -294,7 +291,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
translate('MediaPlugin.MediaItem', 'Unsupported File'))
|
||||
return False
|
||||
self.set_controls_visible(controller, True)
|
||||
log.debug('use %s controller' % self.current_media_players[controller.controller_type].display_name)
|
||||
log.debug('use {nm} controller'.format(nm=self.current_media_players[controller.controller_type].display_name))
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
@ -580,7 +577,7 @@ class MediaController(RegistryBase, LogMixin, RegistryProperties):
|
||||
:param controller: The Controller to use
|
||||
:param volume: The volume to be set
|
||||
"""
|
||||
log.debug('media_volume %d' % volume)
|
||||
log.debug('media_volume {vol}'.format(vol=volume))
|
||||
display = self._define_display(controller)
|
||||
self.current_media_players[controller.controller_type].volume(display, volume)
|
||||
controller.volume_slider.setValue(volume)
|
||||
|
@ -29,14 +29,14 @@ import sys
|
||||
import threading
|
||||
from datetime import datetime
|
||||
|
||||
from PyQt5 import QtWidgets
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.common import is_linux, is_macosx, is_win
|
||||
from openlp.core.common.settings import Settings
|
||||
from openlp.core.display.screens import ScreenList
|
||||
from openlp.core.ui.media import MediaState, MediaType
|
||||
from openlp.core.ui.media.mediaplayer import MediaPlayer
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Audio and video extensions copied from 'include/vlc_interface.h' from vlc 2.2.0 source
|
||||
@ -105,8 +105,14 @@ class VlcPlayer(MediaPlayer):
|
||||
:return:
|
||||
"""
|
||||
vlc = get_vlc()
|
||||
if output_display.is_display:
|
||||
output_display.vlc_widget = QtWidgets.QFrame()
|
||||
output_display.vlc_widget.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool |
|
||||
QtCore.Qt.WindowStaysOnTopHint)
|
||||
else:
|
||||
output_display.vlc_widget = QtWidgets.QFrame(output_display)
|
||||
output_display.vlc_widget.setFrameStyle(QtWidgets.QFrame.NoFrame)
|
||||
|
||||
# creating a basic vlc instance
|
||||
command_line_options = '--no-video-title-show '
|
||||
if Settings().value('advanced/hide mouse') and live_display:
|
||||
@ -206,6 +212,9 @@ class VlcPlayer(MediaPlayer):
|
||||
:param output_display: The display where the media is
|
||||
:return:
|
||||
"""
|
||||
if output_display.is_display:
|
||||
output_display.vlc_widget.setGeometry(ScreenList().current.display_geometry)
|
||||
else:
|
||||
output_display.vlc_widget.resize(output_display.size())
|
||||
|
||||
def play(self, controller, output_display):
|
||||
|
@ -47,7 +47,6 @@ from openlp.core.widgets.layouts import AspectRatioLayout
|
||||
from openlp.core.widgets.toolbar import OpenLPToolbar
|
||||
from openlp.core.widgets.views import ListPreviewWidget
|
||||
|
||||
|
||||
# Threshold which has to be trespassed to toggle.
|
||||
HIDE_MENU_THRESHOLD = 27
|
||||
|
||||
@ -863,6 +862,7 @@ class SlideController(QtWidgets.QWidget, LogMixin, RegistryProperties):
|
||||
[self.service_item, self.is_live, self.hide_mode(), slide_no])
|
||||
else:
|
||||
# Get theme
|
||||
# TODO this is wrong!!!
|
||||
theme_name = service_item.theme if service_item.theme else Registry().get('theme_manager').global_theme
|
||||
theme_data = Registry().get('theme_manager').get_theme_data(theme_name)
|
||||
# Set theme for preview
|
||||
|
@ -25,7 +25,6 @@ import os
|
||||
|
||||
from PyQt5 import QtCore, QtWidgets
|
||||
|
||||
from openlp.core.state import State
|
||||
from openlp.core.common.applocation import AppLocation
|
||||
from openlp.core.common.i18n import UiStrings, get_natural_key, translate
|
||||
from openlp.core.common.mixins import RegistryProperties
|
||||
@ -36,11 +35,11 @@ from openlp.core.lib import MediaType, ServiceItemContext, check_item_selected
|
||||
from openlp.core.lib.mediamanageritem import MediaManagerItem
|
||||
from openlp.core.lib.serviceitem import ItemCapabilities
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.state import State
|
||||
from openlp.core.ui.icons import UiIcons
|
||||
from openlp.core.ui.media import parse_optical_path, format_milliseconds, AUDIO_EXT, VIDEO_EXT
|
||||
from openlp.core.ui.media.vlcplayer import get_vlc
|
||||
|
||||
|
||||
if get_vlc() is not None:
|
||||
from openlp.plugins.media.forms.mediaclipselectorform import MediaClipSelectorForm
|
||||
|
||||
@ -128,36 +127,6 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
||||
tooltip=optical_button_tooltip,
|
||||
triggers=self.on_load_optical)
|
||||
|
||||
def add_end_header_bar(self):
|
||||
"""
|
||||
Adds buttons to the end of the header bar.
|
||||
"""
|
||||
# Replace backgrounds do not work at present so remove functionality.
|
||||
# self.replace_action = self.toolbar.add_toolbar_action('replace_action', icon=UiIcons().theme,
|
||||
# triggers=self.on_replace_click)
|
||||
# if 'webkit' not in get_media_players()[0]:
|
||||
# self.replace_action.setDisabled(True)
|
||||
# if hasattr(self, 'replace_action_context'):
|
||||
# self.replace_action_context.setDisabled(True)
|
||||
# self.reset_action = self.toolbar.add_toolbar_action('reset_action', icon=UiIcons().close,
|
||||
# visible=False, triggers=self.on_reset_click)
|
||||
# self.media_widget = QtWidgets.QWidget(self)
|
||||
# self.media_widget.setObjectName('media_widget')
|
||||
# self.display_layout = QtWidgets.QFormLayout(self.media_widget)
|
||||
# self.display_layout.setContentsMargins(self.display_layout.spacing(), self.display_layout.spacing(),
|
||||
# self.display_layout.spacing(), self.display_layout.spacing())
|
||||
# self.display_layout.setObjectName('display_layout')
|
||||
# self.display_type_label = QtWidgets.QLabel(self.media_widget)
|
||||
# self.display_type_label.setObjectName('display_type_label')
|
||||
# self.display_type_combo_box = create_horizontal_adjusting_combo_box(
|
||||
# self.media_widget, 'display_type_combo_box')
|
||||
# self.display_type_label.setBuddy(self.display_type_combo_box)
|
||||
# self.display_layout.addRow(self.display_type_label, self.display_type_combo_box)
|
||||
# Add the Media widget to the page layout.
|
||||
# self.page_layout.addWidget(self.media_widget)
|
||||
# self.display_type_combo_box.currentIndexChanged.connect(self.override_player_changed)
|
||||
pass
|
||||
|
||||
def generate_slide_data(self, service_item, *, item=None, remote=False, context=ServiceItemContext.Service,
|
||||
**kwargs):
|
||||
"""
|
||||
@ -175,7 +144,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
||||
return False
|
||||
filename = str(item.data(QtCore.Qt.UserRole))
|
||||
# Special handling if the filename is a optical clip
|
||||
if filename == 'live':
|
||||
if filename == UiStrings().LiveStream:
|
||||
service_item.processor = 'vlc'
|
||||
service_item.title = filename
|
||||
service_item.add_capability(ItemCapabilities.CanStream)
|
||||
@ -265,7 +234,7 @@ class MediaMediaItem(MediaManagerItem, RegistryProperties):
|
||||
file_name = translate('MediaPlugin.MediaItem', 'Live Stream')
|
||||
item_name = QtWidgets.QListWidgetItem(file_name)
|
||||
item_name.setIcon(UiIcons().video)
|
||||
item_name.setData(QtCore.Qt.UserRole, 'live')
|
||||
item_name.setData(QtCore.Qt.UserRole, UiStrings().LiveStream)
|
||||
item_name.setToolTip(translate('MediaPlugin.MediaItem', 'Show Live Stream'))
|
||||
self.list_view.addItem(item_name)
|
||||
for track in media:
|
||||
|
@ -1,181 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'auditdetaildialog.ui'
|
||||
#
|
||||
# Created: Sun Oct 11 11:40:02 2009
|
||||
# by: PyQt4 UI code generator 4.5.4
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
|
||||
class Ui_AuditDetailDialog(object):
|
||||
def setupUi(self, AuditDetailDialog):
|
||||
AuditDetailDialog.setObjectName(u'AuditDetailDialog')
|
||||
AuditDetailDialog.resize(593, 501)
|
||||
self.buttonBox = QtGui.QDialogButtonBox(AuditDetailDialog)
|
||||
self.buttonBox.setGeometry(QtCore.QRect(420, 470, 170, 25))
|
||||
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok)
|
||||
self.buttonBox.setObjectName(u'buttonBox')
|
||||
self.FileGroupBox = QtGui.QGroupBox(AuditDetailDialog)
|
||||
self.FileGroupBox.setGeometry(QtCore.QRect(10, 370, 571, 70))
|
||||
self.FileGroupBox.setObjectName(u'FileGroupBox')
|
||||
self.verticalLayout_4 = QtGui.QVBoxLayout(self.FileGroupBox)
|
||||
self.verticalLayout_4.setObjectName(u'verticalLayout_4')
|
||||
self.horizontalLayout = QtGui.QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName(u'horizontalLayout')
|
||||
self.FileLineEdit = QtGui.QLineEdit(self.FileGroupBox)
|
||||
self.FileLineEdit.setObjectName(u'FileLineEdit')
|
||||
self.horizontalLayout.addWidget(self.FileLineEdit)
|
||||
self.SaveFilePushButton = QtGui.QPushButton(self.FileGroupBox)
|
||||
icon = QtGui.QIcon()
|
||||
icon.addPixmap(QtGui.QPixmap(u':/exports/export_load.png'),
|
||||
QtGui.QIcon.Normal, QtGui.QIcon.Off)
|
||||
self.SaveFilePushButton.setIcon(icon)
|
||||
self.SaveFilePushButton.setObjectName(u'SaveFilePushButton')
|
||||
self.horizontalLayout.addWidget(self.SaveFilePushButton)
|
||||
self.verticalLayout_4.addLayout(self.horizontalLayout)
|
||||
self.layoutWidget = QtGui.QWidget(AuditDetailDialog)
|
||||
self.layoutWidget.setGeometry(QtCore.QRect(10, 10, 561, 361))
|
||||
self.layoutWidget.setObjectName(u'layoutWidget')
|
||||
self.verticalLayout_3 = QtGui.QVBoxLayout(self.layoutWidget)
|
||||
self.verticalLayout_3.setObjectName(u'verticalLayout_3')
|
||||
self.ReportTypeGroup = QtGui.QGroupBox(self.layoutWidget)
|
||||
self.ReportTypeGroup.setObjectName(u'ReportTypeGroup')
|
||||
self.layoutWidget1 = QtGui.QWidget(self.ReportTypeGroup)
|
||||
self.layoutWidget1.setGeometry(QtCore.QRect(50, 40, 481, 23))
|
||||
self.layoutWidget1.setObjectName(u'layoutWidget1')
|
||||
self.ReportHorizontalLayout = QtGui.QHBoxLayout(self.layoutWidget1)
|
||||
self.ReportHorizontalLayout.setObjectName(u'ReportHorizontalLayout')
|
||||
self.SummaryReport = QtGui.QRadioButton(self.layoutWidget1)
|
||||
self.SummaryReport.setObjectName(u'SummaryReport')
|
||||
self.ReportHorizontalLayout.addWidget(self.SummaryReport)
|
||||
self.DetailedReport = QtGui.QRadioButton(self.layoutWidget1)
|
||||
self.DetailedReport.setChecked(True)
|
||||
self.DetailedReport.setObjectName(u'DetailedReport')
|
||||
self.ReportHorizontalLayout.addWidget(self.DetailedReport)
|
||||
self.verticalLayout_3.addWidget(self.ReportTypeGroup)
|
||||
self.DateRangeGroupBox = QtGui.QGroupBox(self.layoutWidget)
|
||||
self.DateRangeGroupBox.setObjectName(u'DateRangeGroupBox')
|
||||
self.verticalLayout_2 = QtGui.QVBoxLayout(self.DateRangeGroupBox)
|
||||
self.verticalLayout_2.setObjectName(u'verticalLayout_2')
|
||||
self.DateHorizontalLayout = QtGui.QHBoxLayout()
|
||||
self.DateHorizontalLayout.setObjectName(u'DateHorizontalLayout')
|
||||
self.FromDateEdit = QtGui.QDateEdit(self.DateRangeGroupBox)
|
||||
self.FromDateEdit.setCalendarPopup(True)
|
||||
self.FromDateEdit.setObjectName(u'FromDateEdit')
|
||||
self.DateHorizontalLayout.addWidget(self.FromDateEdit)
|
||||
self.To = QtGui.QLabel(self.DateRangeGroupBox)
|
||||
self.To.setObjectName(u'To')
|
||||
self.DateHorizontalLayout.addWidget(self.To)
|
||||
self.ToDateEdit = QtGui.QDateEdit(self.DateRangeGroupBox)
|
||||
self.ToDateEdit.setCalendarPopup(True)
|
||||
self.ToDateEdit.setObjectName(u'ToDateEdit')
|
||||
self.DateHorizontalLayout.addWidget(self.ToDateEdit)
|
||||
self.verticalLayout_2.addLayout(self.DateHorizontalLayout)
|
||||
self.verticalLayout_3.addWidget(self.DateRangeGroupBox)
|
||||
self.TimePeriodGroupBox = QtGui.QGroupBox(self.layoutWidget)
|
||||
self.TimePeriodGroupBox.setObjectName(u'TimePeriodGroupBox')
|
||||
self.verticalLayout = QtGui.QVBoxLayout(self.TimePeriodGroupBox)
|
||||
self.verticalLayout.setObjectName(u'verticalLayout')
|
||||
self.FirstHorizontalLayout = QtGui.QHBoxLayout()
|
||||
self.FirstHorizontalLayout.setObjectName(u'FirstHorizontalLayout')
|
||||
self.FirstCheckBox = QtGui.QCheckBox(self.TimePeriodGroupBox)
|
||||
self.FirstCheckBox.setChecked(True)
|
||||
self.FirstCheckBox.setObjectName(u'FirstCheckBox')
|
||||
self.FirstHorizontalLayout.addWidget(self.FirstCheckBox)
|
||||
self.FirstFromTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox)
|
||||
self.FirstFromTimeEdit.setTime(QtCore.QTime(9, 0, 0))
|
||||
self.FirstFromTimeEdit.setObjectName(u'FirstFromTimeEdit')
|
||||
self.FirstHorizontalLayout.addWidget(self.FirstFromTimeEdit)
|
||||
self.FirstTo = QtGui.QLabel(self.TimePeriodGroupBox)
|
||||
self.FirstTo.setObjectName(u'FirstTo')
|
||||
self.FirstHorizontalLayout.addWidget(self.FirstTo)
|
||||
self.FirstToTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox)
|
||||
self.FirstToTimeEdit.setCalendarPopup(True)
|
||||
self.FirstToTimeEdit.setTime(QtCore.QTime(10, 0, 0))
|
||||
self.FirstToTimeEdit.setObjectName(u'FirstToTimeEdit')
|
||||
self.FirstHorizontalLayout.addWidget(self.FirstToTimeEdit)
|
||||
self.verticalLayout.addLayout(self.FirstHorizontalLayout)
|
||||
self.SecondHorizontalLayout = QtGui.QHBoxLayout()
|
||||
self.SecondHorizontalLayout.setObjectName(u'SecondHorizontalLayout')
|
||||
self.SecondCheckBox = QtGui.QCheckBox(self.TimePeriodGroupBox)
|
||||
self.SecondCheckBox.setChecked(True)
|
||||
self.SecondCheckBox.setObjectName(u'SecondCheckBox')
|
||||
self.SecondHorizontalLayout.addWidget(self.SecondCheckBox)
|
||||
self.SecondFromTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox)
|
||||
self.SecondFromTimeEdit.setTime(QtCore.QTime(10, 45, 0))
|
||||
self.SecondFromTimeEdit.setObjectName(u'SecondFromTimeEdit')
|
||||
self.SecondHorizontalLayout.addWidget(self.SecondFromTimeEdit)
|
||||
self.SecondTo = QtGui.QLabel(self.TimePeriodGroupBox)
|
||||
self.SecondTo.setObjectName(u'SecondTo')
|
||||
self.SecondHorizontalLayout.addWidget(self.SecondTo)
|
||||
self.SecondToTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox)
|
||||
self.SecondToTimeEdit.setObjectName(u'SecondToTimeEdit')
|
||||
self.SecondHorizontalLayout.addWidget(self.SecondToTimeEdit)
|
||||
self.verticalLayout.addLayout(self.SecondHorizontalLayout)
|
||||
self.ThirdHorizontalLayout = QtGui.QHBoxLayout()
|
||||
self.ThirdHorizontalLayout.setObjectName(u'ThirdHorizontalLayout')
|
||||
self.ThirdCheckBox = QtGui.QCheckBox(self.TimePeriodGroupBox)
|
||||
self.ThirdCheckBox.setChecked(True)
|
||||
self.ThirdCheckBox.setObjectName(u'ThirdCheckBox')
|
||||
self.ThirdHorizontalLayout.addWidget(self.ThirdCheckBox)
|
||||
self.ThirdFromTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox)
|
||||
self.ThirdFromTimeEdit.setTime(QtCore.QTime(18, 30, 0))
|
||||
self.ThirdFromTimeEdit.setObjectName(u'ThirdFromTimeEdit')
|
||||
self.ThirdHorizontalLayout.addWidget(self.ThirdFromTimeEdit)
|
||||
self.ThirdTo = QtGui.QLabel(self.TimePeriodGroupBox)
|
||||
self.ThirdTo.setObjectName(u'ThirdTo')
|
||||
self.ThirdHorizontalLayout.addWidget(self.ThirdTo)
|
||||
self.ThirdToTimeEdit = QtGui.QTimeEdit(self.TimePeriodGroupBox)
|
||||
self.ThirdToTimeEdit.setTime(QtCore.QTime(19, 30, 0))
|
||||
self.ThirdToTimeEdit.setObjectName(u'ThirdToTimeEdit')
|
||||
self.ThirdHorizontalLayout.addWidget(self.ThirdToTimeEdit)
|
||||
self.verticalLayout.addLayout(self.ThirdHorizontalLayout)
|
||||
self.verticalLayout_3.addWidget(self.TimePeriodGroupBox)
|
||||
|
||||
self.retranslateUi(AuditDetailDialog)
|
||||
QtCore.QObject.connect(
|
||||
self.buttonBox, QtCore.SIGNAL(u'accepted()'),
|
||||
AuditDetailDialog.accept)
|
||||
QtCore.QObject.connect(
|
||||
self.buttonBox, QtCore.SIGNAL(u'rejected()'),
|
||||
AuditDetailDialog.close)
|
||||
QtCore.QObject.connect(
|
||||
self.FirstCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
|
||||
AuditDetailDialog.changeFirstService)
|
||||
QtCore.QObject.connect(
|
||||
self.SecondCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
|
||||
AuditDetailDialog.changeSecondService)
|
||||
QtCore.QObject.connect(
|
||||
self.ThirdCheckBox, QtCore.SIGNAL(u'stateChanged(int)'),
|
||||
AuditDetailDialog.changeThirdService)
|
||||
QtCore.QObject.connect(
|
||||
self.SaveFilePushButton, QtCore.SIGNAL(u'pressed()'),
|
||||
AuditDetailDialog.defineOutputLocation)
|
||||
QtCore.QMetaObject.connectSlotsByName(AuditDetailDialog)
|
||||
|
||||
def retranslateUi(self, AuditDetailDialog):
|
||||
AuditDetailDialog.setWindowTitle(self.trUtf8(u'Audit Detail Extraction'))
|
||||
self.FileGroupBox.setTitle(self.trUtf8(u'Report Location'))
|
||||
self.ReportTypeGroup.setTitle(self.trUtf8(u'Report Type'))
|
||||
self.SummaryReport.setText(self.trUtf8(u'Summary'))
|
||||
self.DetailedReport.setText(self.trUtf8(u'Detailed'))
|
||||
self.DateRangeGroupBox.setTitle(self.trUtf8(u'Select Date Range'))
|
||||
self.FromDateEdit.setDisplayFormat(self.trUtf8(u'dd/MM/yyyy'))
|
||||
self.To.setText(self.trUtf8(u'to'))
|
||||
self.ToDateEdit.setDisplayFormat(self.trUtf8(u'dd/MM/yyyy'))
|
||||
self.TimePeriodGroupBox.setTitle(self.trUtf8(u'Select Time Periods'))
|
||||
self.FirstCheckBox.setText(self.trUtf8(u'First Service'))
|
||||
self.FirstFromTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP'))
|
||||
self.FirstTo.setText(self.trUtf8(u'to'))
|
||||
self.FirstToTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP'))
|
||||
self.SecondCheckBox.setText(self.trUtf8(u'Second Service'))
|
||||
self.SecondFromTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP'))
|
||||
self.SecondTo.setText(self.trUtf8(u'to'))
|
||||
self.SecondToTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP'))
|
||||
self.ThirdCheckBox.setText(self.trUtf8(u'Third Service'))
|
||||
self.ThirdFromTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP'))
|
||||
self.ThirdTo.setText(self.trUtf8(u'to'))
|
||||
self.ThirdToTimeEdit.setDisplayFormat(self.trUtf8(u'hh:mm AP'))
|
@ -1,121 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
|
||||
|
||||
###############################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2009 Raoul Snyman #
|
||||
# Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, Carsten #
|
||||
# Tinggaard, Jon Tibble, Jonathan Corwin, Maikel Stuivenberg, Scott Guerrieri #
|
||||
# --------------------------------------------------------------------------- #
|
||||
# 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 #
|
||||
###############################################################################
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from auditdetaildialog import Ui_AuditDetailDialog
|
||||
|
||||
|
||||
class AuditDetailForm(QtGui.QDialog, Ui_AuditDetailDialog):
|
||||
"""
|
||||
Class documentation goes here.
|
||||
"""
|
||||
def __init__(self, parent=None):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, None)
|
||||
self.parent = parent
|
||||
self.setupUi(self)
|
||||
|
||||
def initialise(self):
|
||||
self.FirstCheckBox.setCheckState(
|
||||
int(self.parent.config.get_config(u'first service', QtCore.Qt.Checked)))
|
||||
self.SecondCheckBox.setCheckState(
|
||||
int(self.parent.config.get_config(u'second service', QtCore.Qt.Checked)))
|
||||
self.ThirdCheckBox.setCheckState(
|
||||
int(self.parent.config.get_config(u'third service', QtCore.Qt.Checked)))
|
||||
year = QtCore.QDate().currentDate().year()
|
||||
if QtCore.QDate().currentDate().month() < 9:
|
||||
year -= 1
|
||||
toDate = QtCore.QDate(year, 8, 31)
|
||||
fromDate = QtCore.QDate(year - 1, 9, 1)
|
||||
self.FromDateEdit.setDate(fromDate)
|
||||
self.ToDateEdit.setDate(toDate)
|
||||
self.FileLineEdit.setText(self.parent.config.get_last_dir(1))
|
||||
self.resetWindow()
|
||||
|
||||
def changeFirstService(self, value):
|
||||
self.parent.config.set_config(u'first service', value)
|
||||
self.resetWindow()
|
||||
|
||||
def changeSecondService(self, value):
|
||||
self.parent.config.set_config(u'second service', value)
|
||||
self.resetWindow()
|
||||
|
||||
def changeThirdService(self, value):
|
||||
self.parent.config.set_config(u'third service', value)
|
||||
self.resetWindow()
|
||||
|
||||
def defineOutputLocation(self):
|
||||
path = QtGui.QFileDialog.getExistingDirectory(self, self.trUtf8(u'Output File Location'),
|
||||
self.parent.config.get_last_dir(1))
|
||||
if path != u'':
|
||||
self.parent.config.set_last_dir(path, 1)
|
||||
self.FileLineEdit.setText(path)
|
||||
|
||||
def resetWindow(self):
|
||||
if self.FirstCheckBox.checkState() == QtCore.Qt.Unchecked:
|
||||
self.FirstFromTimeEdit.setEnabled(False)
|
||||
self.FirstToTimeEdit.setEnabled(False)
|
||||
else:
|
||||
self.FirstFromTimeEdit.setEnabled(True)
|
||||
self.FirstToTimeEdit.setEnabled(True)
|
||||
if self.SecondCheckBox.checkState() == QtCore.Qt.Unchecked:
|
||||
self.SecondFromTimeEdit.setEnabled(False)
|
||||
self.SecondToTimeEdit.setEnabled(False)
|
||||
else:
|
||||
self.SecondFromTimeEdit.setEnabled(True)
|
||||
self.SecondToTimeEdit.setEnabled(True)
|
||||
if self.ThirdCheckBox.checkState() == QtCore.Qt.Unchecked:
|
||||
self.ThirdFromTimeEdit.setEnabled(False)
|
||||
self.ThirdToTimeEdit.setEnabled(False)
|
||||
else:
|
||||
self.ThirdFromTimeEdit.setEnabled(True)
|
||||
self.ThirdToTimeEdit.setEnabled(True)
|
||||
|
||||
def accept(self):
|
||||
print(self.DetailedReport.isChecked())
|
||||
print(self.SummaryReport.isChecked())
|
||||
print(self.FromDateEdit.date())
|
||||
print(self.ToDateEdit.date())
|
||||
if self.DetailedReport.isChecked():
|
||||
self.detailedReport()
|
||||
else:
|
||||
self.summaryReport()
|
||||
self.close()
|
||||
|
||||
def detailedReport(self):
|
||||
print("detailed")
|
||||
filename = u'audit_det_%s_%s.txt' % \
|
||||
(self.FromDateEdit.date().toString(u'ddMMyyyy'),
|
||||
self.ToDateEdit.date().toString(u'ddMMyyyy'))
|
||||
print(filename)
|
||||
|
||||
def summaryReport(self):
|
||||
print("summary")
|
||||
filename = u'audit_sum_%s_%s.txt' % \
|
||||
(self.FromDateEdit.date().toString(u'ddMMyyyy'),
|
||||
self.ToDateEdit.date().toString(u'ddMMyyyy'))
|
||||
print(filename)
|
@ -1,258 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
|
||||
|
||||
##########################################################################
|
||||
# OpenLP - Open Source Lyrics Projection #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# Copyright (c) 2008-2019 OpenLP Developers #
|
||||
# ---------------------------------------------------------------------- #
|
||||
# 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 3 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, see <https://www.gnu.org/licenses/>. #
|
||||
##########################################################################
|
||||
"""
|
||||
This script helps to trigger builds of branches. To use it you have to install the python-jenkins module. On Fedora
|
||||
and Ubuntu/Debian, it is available as the ``python3-jenkins`` package::
|
||||
|
||||
$ sudo dnf/apt install python3-jenkins
|
||||
|
||||
To make it easier to run you may want to create a shell script or an alias. To create an alias, add this to your
|
||||
``~/.bashrc`` (or ``~/.zshrc``) file and then log out and log back in again (to apply the alias)::
|
||||
|
||||
alias ci="python3 /path/to/openlp_root/scripts/jenkins_script.py -u USERNAME -p PASSWORD"
|
||||
|
||||
To create a shell script, create the following file in a location in your ``$PATH`` (I called mine ``ci``)::
|
||||
|
||||
#!/bin/bash
|
||||
python3 /path/to/openlp_root/scripts/jenkins_script.py -u USERNAME -p PASSWORD
|
||||
|
||||
``USERNAME`` is your Jenkins username, and ``PASSWORD`` is your Jenkins password or personal token.
|
||||
|
||||
An older version of this script used to use a shared TOKEN, but this has been replaced with the username and password.
|
||||
"""
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
from argparse import ArgumentParser
|
||||
from subprocess import PIPE, Popen
|
||||
|
||||
from jenkins import Jenkins
|
||||
|
||||
|
||||
JENKINS_URL = 'https://ci.openlp.io/'
|
||||
REPO_REGEX = r'(.*/+)(~.*)'
|
||||
|
||||
|
||||
class OpenLPJobs(object):
|
||||
"""
|
||||
This class holds any jobs we have on jenkins and we actually need in this script.
|
||||
"""
|
||||
Branch_Pull = 'Branch-01-Pull'
|
||||
Branch_Linux_Tests = 'Branch-02a-Linux-Tests'
|
||||
Branch_macOS_Tests = 'Branch-02b-macOS-Tests'
|
||||
Branch_Build_Source = 'Branch-03a-Build-Source'
|
||||
Branch_Build_macOS = 'Branch-03b-Build-macOS'
|
||||
Branch_Code_Analysis = 'Branch-04a-Code-Lint'
|
||||
Branch_Test_Coverage = 'Branch-04b-Test-Coverage'
|
||||
Branch_Lint_Check = 'Branch-04c-Lint-Check'
|
||||
Branch_AppVeyor_Tests = 'Branch-05-AppVeyor-Tests'
|
||||
|
||||
Jobs = [Branch_Pull, Branch_Linux_Tests, Branch_macOS_Tests, Branch_Build_Source, Branch_Build_macOS,
|
||||
Branch_Code_Analysis, Branch_Test_Coverage, Branch_AppVeyor_Tests]
|
||||
|
||||
|
||||
class Colour(object):
|
||||
"""
|
||||
This class holds values which can be used to print coloured text.
|
||||
"""
|
||||
RED_START = '\033[1;31m'
|
||||
RED_END = '\033[1;m'
|
||||
GREEN_START = '\033[1;32m'
|
||||
GREEN_END = '\033[1;m'
|
||||
|
||||
|
||||
class JenkinsTrigger(object):
|
||||
"""
|
||||
A class to trigger builds on Jenkins and print the results.
|
||||
"""
|
||||
|
||||
def __init__(self, username, password, can_use_colour):
|
||||
"""
|
||||
Create the JenkinsTrigger instance.
|
||||
"""
|
||||
self.jobs = {}
|
||||
self.can_use_colour = can_use_colour and not os.name.startswith('nt')
|
||||
self.repo_name = get_repo_name()
|
||||
self.server = Jenkins(JENKINS_URL, username=username, password=password)
|
||||
|
||||
def fetch_jobs(self):
|
||||
"""
|
||||
Get the job info for all the jobs
|
||||
"""
|
||||
for job_name in OpenLPJobs.Jobs:
|
||||
try:
|
||||
job_info = self.server.get_job_info(job_name)
|
||||
self.jobs[job_name] = job_info
|
||||
self.jobs[job_name]['nextBuildUrl'] = '{url}{nextBuildNumber}/'.format(**job_info)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def trigger_build(self):
|
||||
"""
|
||||
Ask our jenkins server to build the "Branch-01-Pull" job.
|
||||
"""
|
||||
bzr = Popen(('bzr', 'whoami'), stdout=PIPE, stderr=PIPE)
|
||||
raw_output, error = bzr.communicate()
|
||||
# We just want the name (not the email).
|
||||
name = ' '.join(raw_output.decode().split()[:-1])
|
||||
cause = 'Build triggered by %s (%s)' % (name, self.repo_name)
|
||||
self.fetch_jobs()
|
||||
self.server.build_job(OpenLPJobs.Branch_Pull, {'BRANCH_NAME': self.repo_name, 'cause': cause})
|
||||
|
||||
def print_output(self, can_continue=False):
|
||||
"""
|
||||
Print the status information of the build triggered.
|
||||
"""
|
||||
print('Add this to your merge proposal:')
|
||||
print('-' * 80)
|
||||
bzr = Popen(('bzr', 'revno'), stdout=PIPE, stderr=PIPE)
|
||||
raw_output, error = bzr.communicate()
|
||||
revno = raw_output.decode().strip()
|
||||
print('%s (revision %s)' % (get_repo_name(), revno))
|
||||
|
||||
failed_builds = []
|
||||
for job in OpenLPJobs.Jobs:
|
||||
if not self.__print_build_info(job):
|
||||
if self.current_build:
|
||||
failed_builds.append((self.current_build['fullDisplayName'], self.current_build['url']))
|
||||
if not can_continue:
|
||||
print('Stopping after failure')
|
||||
break
|
||||
print('')
|
||||
if failed_builds:
|
||||
print('Failed builds:')
|
||||
for build_name, url in failed_builds:
|
||||
print(' - {}: {}console'.format(build_name, url))
|
||||
else:
|
||||
print('All builds passed')
|
||||
|
||||
def open_browser(self):
|
||||
"""
|
||||
Opens the browser.
|
||||
"""
|
||||
url = self.jenkins_instance.job(OpenLPJobs.Branch_Pull).info['url']
|
||||
# Open the url
|
||||
Popen(('xdg-open', url), stderr=PIPE)
|
||||
|
||||
def _get_build_info(self, job_name, build_number):
|
||||
"""
|
||||
Get the build info from the server. This method will check the queue and wait for the build.
|
||||
"""
|
||||
queue_info = self.server.get_queue_info()
|
||||
tries = 0
|
||||
loop_count = 100
|
||||
while queue_info and tries < loop_count:
|
||||
tries += 1
|
||||
time.sleep(1)
|
||||
queue_info = self.server.get_queue_info()
|
||||
if tries >= loop_count:
|
||||
raise Exception('Build has not started yet, it may be stuck in the queue.')
|
||||
return self.server.get_build_info(job_name, build_number)
|
||||
|
||||
def __print_build_info(self, job_name):
|
||||
"""
|
||||
This helper method prints the job information of the given ``job_name``
|
||||
|
||||
:param job_name: The name of the job we want the information from. For example *Branch-01-Pull*. Use the class
|
||||
variables from the :class:`OpenLPJobs` class.
|
||||
"""
|
||||
job = self.jobs[job_name]
|
||||
print('{:<70} [WAITING]'.format(job['nextBuildUrl']), end='', flush=True)
|
||||
self.current_build = self._get_build_info(job_name, job['nextBuildNumber'])
|
||||
print('\b\b\b\b\b\b\b\b\b[RUNNING]', end='', flush=True)
|
||||
while self.current_build['building'] is True:
|
||||
time.sleep(0.5)
|
||||
self.current_build = self.server.get_build_info(job_name, job['nextBuildNumber'])
|
||||
result_string = self.current_build['result']
|
||||
is_success = result_string == 'SUCCESS'
|
||||
if self.can_use_colour:
|
||||
if is_success:
|
||||
# Make 'SUCCESS' green.
|
||||
result_string = '{}{}{}'.format(Colour.GREEN_START, result_string, Colour.GREEN_END)
|
||||
else:
|
||||
# Make 'FAILURE' red.
|
||||
result_string = '{}{}{}'.format(Colour.RED_START, result_string, Colour.RED_END)
|
||||
print('\b\b\b\b\b\b\b\b\b[{:>7}]'.format(result_string))
|
||||
return is_success
|
||||
|
||||
|
||||
def get_repo_name():
|
||||
"""
|
||||
This returns the name of branch of the working directory. For example it returns *lp:~googol/openlp/render*.
|
||||
"""
|
||||
# Run the bzr command.
|
||||
bzr = Popen(('bzr', 'info'), stdout=PIPE, stderr=PIPE)
|
||||
raw_output, error = bzr.communicate()
|
||||
# Detect any errors
|
||||
if error:
|
||||
print('This is not a branch.')
|
||||
return
|
||||
# Clean the output.
|
||||
raw_output = raw_output.decode()
|
||||
output_list = list(map(str.strip, raw_output.split('\n')))
|
||||
# Determine the branch's name
|
||||
repo_name = ''
|
||||
for line in output_list:
|
||||
# Check if it is api branch.
|
||||
if 'push branch' in line:
|
||||
match = re.match(REPO_REGEX, line)
|
||||
if match:
|
||||
repo_name = 'lp:%s' % match.group(2)
|
||||
break
|
||||
elif 'checkout of branch' in line:
|
||||
match = re.match(REPO_REGEX, line)
|
||||
if match:
|
||||
repo_name = 'lp:%s' % match.group(2)
|
||||
break
|
||||
return repo_name.strip('/')
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Run the script
|
||||
"""
|
||||
parser = ArgumentParser()
|
||||
parser.add_argument('-d', '--disable-output', action='store_true', default=False, help='Disable output')
|
||||
parser.add_argument('-b', '--open-browser', action='store_true', default=False,
|
||||
help='Opens the jenkins page in your browser')
|
||||
parser.add_argument('-n', '--no-colour', action='store_true', default=False,
|
||||
help='Disable coloured output (always disabled on Windows)')
|
||||
parser.add_argument('-u', '--username', required=True, help='Your Jenkins username')
|
||||
parser.add_argument('-p', '--password', required=True, help='Your Jenkins password or personal token')
|
||||
parser.add_argument('-c', '--always-continue', action='store_true', default=False, help='Continue despite failure')
|
||||
args = parser.parse_args()
|
||||
|
||||
if not get_repo_name():
|
||||
print('Not a branch. Have you pushed it to launchpad? Did you cd to the branch?')
|
||||
return
|
||||
jenkins_trigger = JenkinsTrigger(args.username, args.password, not args.no_colour)
|
||||
jenkins_trigger.trigger_build()
|
||||
# Open the browser before printing the output.
|
||||
if args.open_browser:
|
||||
jenkins_trigger.open_browser()
|
||||
if not args.disable_output:
|
||||
jenkins_trigger.print_output(can_continue=args.always_continue)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -565,6 +565,7 @@ class TestVLCPlayer(TestCase, TestMixin):
|
||||
# GIVEN: A display object and a VlcPlayer instance
|
||||
mocked_display = MagicMock()
|
||||
mocked_display.size.return_value = (10, 10)
|
||||
mocked_display.is_display = False
|
||||
vlc_player = VlcPlayer(None)
|
||||
|
||||
# WHEN: resize is called
|
||||
|
Loading…
Reference in New Issue
Block a user