def on_search_button_clicked(self): """ Run a search on SongSelect. """ # Set up UI components self.view_button.setEnabled(False) self.search_button.setEnabled(False) self.search_combobox.setEnabled(False) self.search_progress_bar.setMinimum(0) self.search_progress_bar.setMaximum(0) self.search_progress_bar.setValue(0) self.set_progress_visible(True) self.search_results_widget.clear() self.result_count_label.setText( translate('SongsPlugin.SongSelectForm', 'Found {count:d} song(s)').format(count=self.song_count)) self.application.process_events() self.song_count = 0 search_history = self.search_combobox.getItems() self.settings.setValue( self.plugin.settings_section + '/songselect searches', '|'.join(search_history)) # Create thread and run search worker = SearchWorker(self.song_select_importer, self.search_combobox.currentText()) worker.show_info.connect(self.on_search_show_info) worker.found_song.connect(self.on_search_found_song) worker.finished.connect(self.on_search_finished) run_thread(worker, 'songselect')
def test_run_thread(MockRegistry, MockQThread): """ Test that running a thread works correctly """ # GIVEN: A mocked registry with a main window object mocked_application = MagicMock() mocked_application.worker_threads = {} MockRegistry.return_value.get.return_value = mocked_application # WHEN: run_thread() is called run_thread(MagicMock(), 'test_thread') # THEN: The thread should be in the threads list and the correct methods should have been called assert len(mocked_application.worker_threads.keys() ) == 1, 'There should be 1 item in the list of threads' assert list(mocked_application.worker_threads.keys()) == ['test_thread'], \ 'The test_thread item should be in the list' mocked_worker = mocked_application.worker_threads['test_thread']['worker'] mocked_thread = mocked_application.worker_threads['test_thread']['thread'] mocked_worker.moveToThread.assert_called_once_with(mocked_thread) mocked_thread.started.connect.assert_called_once_with(mocked_worker.start) expected_quit_calls = [ call(mocked_thread.quit), call(mocked_worker.deleteLater) ] assert mocked_worker.quit.connect.call_args_list == expected_quit_calls, \ 'The workers quit signal should be connected twice' assert mocked_thread.finished.connect.call_args_list[0] == call(mocked_thread.deleteLater), \ 'The threads finished signal should be connected to its deleteLater slot' assert mocked_thread.finished.connect.call_count == 2, 'The signal should have been connected twice' mocked_thread.start.assert_called_once_with()
def __init__(self): """ Initialise and start the WebSockets server """ super(WebSocketServer, self).__init__() if not Registry().get_flag('no_web_server'): worker = WebSocketWorker() run_thread(worker, 'websocket_server')
def process_updates(self): """ Flush the queue to updated any data to update """ try: worker = ImageWorker(self) run_thread(worker, 'image_manager') except KeyError: # run_thread() will throw a KeyError if this thread already exists, so ignore it so that we don't # try to start another thread when one is already running pass
def test_run_thread_no_name(): """ Test that trying to run a thread without a name results in an exception being thrown """ # GIVEN: A fake worker # WHEN: run_thread() is called without a name try: run_thread(MagicMock(), '') assert False, 'A ValueError should have been thrown to prevent blank names' except ValueError: # THEN: A ValueError should have been thrown assert True, 'A ValueError was correctly thrown'
def start_zeroconf(): """ Start the Zeroconf service """ # When we're running tests, just skip this set up if this flag is set if Registry().get_flag('no_web_server'): return http_port = Settings().value('api/port') ws_port = Settings().value('api/websocket port') for name, interface in get_network_interfaces().items(): worker = ZeroconfWorker(interface['ip'], http_port, ws_port) run_thread(worker, 'api_zeroconf_{name}'.format(name=name))
def __init__(self, parent=None): """ Initialise the http server, and start the http server """ super(HttpServer, self).__init__(parent) if not Registry().get_flag('no_web_server'): worker = HttpWorker() run_thread(worker, 'http_server') Registry().register_function('download_website', self.first_time) Registry().register_function('get_website_version', self.website_version) Registry().set_flag('website_version', '0.0')
def check_media(self, path): """ Check if a file can be played Uses a separate QMediaPlayer in a thread :param path: Path to file to be checked :return: True if file can be played otherwise False """ check_media_worker = CheckMediaWorker(path) check_media_worker.setVolume(0) run_thread(check_media_worker, 'check_media') while not is_thread_finished('check_media'): self.application.processEvents() return check_media_worker.result
def __init__(self, themes_url, sample_theme_data, ftw, *args, **kwargs): super().__init__(*args, **kwargs) title = sample_theme_data['title'] thumbnail = sample_theme_data['thumbnail'] self.file_name = sample_theme_data['file_name'] self.sha256 = sample_theme_data['sha256'] self.setIcon(UiIcons().picture) # Set a place holder icon whilst the thumbnails download self.setText(title) self.setToolTip(title) worker = DownloadWorker(themes_url, thumbnail) worker.download_failed.connect(self._on_download_failed) worker.download_succeeded.connect(self._on_thumbnail_downloaded) thread_name = 'thumbnail_download_{thumbnail}'.format(thumbnail=thumbnail) run_thread(worker, thread_name) ftw.thumbnail_download_threads.append(thread_name)
def test_run_thread_exists(MockRegistry): """ Test that trying to run a thread with a name that already exists will throw a KeyError """ # GIVEN: A mocked registry with a main window object mocked_application = MagicMock() mocked_application.worker_threads = {'test_thread': MagicMock()} MockRegistry.return_value.get.return_value = mocked_application # WHEN: run_thread() is called try: run_thread(MagicMock(), 'test_thread') assert False, 'A KeyError should have been thrown to show that a thread with this name already exists' except KeyError: assert True, 'A KeyError was correctly thrown'
def check_for_update(main_window): """ Run a thread to download and check the version of OpenLP :param MainWindow main_window: The OpenLP main window. """ last_check_date = Settings().value('core/last version test') if date.today().strftime('%Y-%m-%d') <= last_check_date: log.debug('Version check skipped, last checked today') return worker = VersionWorker(last_check_date, get_version()) worker.new_version.connect(main_window.on_new_version) worker.quit.connect(update_check_date) # TODO: Use this to figure out if there's an Internet connection? # worker.no_internet.connect(parent.on_no_internet) run_thread(worker, 'version')
def _download_index(self): """ Download the configuration file and kick off the theme screenshot download threads """ # check to see if we have web access self.web_access = False self.config = ConfigParser() user_agent = 'OpenLP/' + Registry().get( 'application').applicationVersion() self.application.process_events() try: web_config = get_web_page('{host}{name}'.format( host=self.web, name='download.cfg'), headers={'User-Agent': user_agent}) except ConnectionError: QtWidgets.QMessageBox.critical( self, translate('OpenLP.FirstTimeWizard', 'Network Error'), translate( 'OpenLP.FirstTimeWizard', 'There was a network error attempting ' 'to connect to retrieve initial configuration information' ), QtWidgets.QMessageBox.Ok) web_config = False if web_config: try: self.config.read_string(web_config) self.web = self.config.get('general', 'base url') self.songs_url = self.web + self.config.get( 'songs', 'directory') + '/' self.bibles_url = self.web + self.config.get( 'bibles', 'directory') + '/' self.themes_url = self.web + self.config.get( 'themes', 'directory') + '/' self.web_access = True except (NoSectionError, NoOptionError, MissingSectionHeaderError): log.debug( 'A problem occurred while parsing the downloaded config file' ) trace_error_handler(log) self.update_screen_list_combo() self.application.process_events() self.downloading = translate('OpenLP.FirstTimeWizard', 'Downloading {name}...') if self.has_run_wizard: self.songs_check_box.setChecked( self.plugin_manager.get_plugin_by_name('songs').is_active()) self.bible_check_box.setChecked( self.plugin_manager.get_plugin_by_name('bibles').is_active()) self.presentation_check_box.setChecked( self.plugin_manager.get_plugin_by_name( 'presentations').is_active()) self.image_check_box.setChecked( self.plugin_manager.get_plugin_by_name('images').is_active()) self.media_check_box.setChecked( self.plugin_manager.get_plugin_by_name('media').is_active()) self.custom_check_box.setChecked( self.plugin_manager.get_plugin_by_name('custom').is_active()) self.song_usage_check_box.setChecked( self.plugin_manager.get_plugin_by_name( 'songusage').is_active()) self.alert_check_box.setChecked( self.plugin_manager.get_plugin_by_name('alerts').is_active()) self.application.set_normal_cursor() # Sort out internet access for downloads if self.web_access: songs = self.config.get('songs', 'languages') songs = songs.split(',') for song in songs: self.application.process_events() title = self.config.get('songs_{song}'.format(song=song), 'title') filename = self.config.get('songs_{song}'.format(song=song), 'filename') sha256 = self.config.get('songs_{song}'.format(song=song), 'sha256', fallback='') item = QtWidgets.QListWidgetItem(title, self.songs_list_widget) item.setData(QtCore.Qt.UserRole, (filename, sha256)) item.setCheckState(QtCore.Qt.Unchecked) item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) bible_languages = self.config.get('bibles', 'languages') bible_languages = bible_languages.split(',') for lang in bible_languages: self.application.process_events() language = self.config.get('bibles_{lang}'.format(lang=lang), 'title') lang_item = QtWidgets.QTreeWidgetItem(self.bibles_tree_widget, [language]) bibles = self.config.get('bibles_{lang}'.format(lang=lang), 'translations') bibles = bibles.split(',') for bible in bibles: self.application.process_events() title = self.config.get( 'bible_{bible}'.format(bible=bible), 'title') filename = self.config.get( 'bible_{bible}'.format(bible=bible), 'filename') sha256 = self.config.get( 'bible_{bible}'.format(bible=bible), 'sha256', fallback='') item = QtWidgets.QTreeWidgetItem(lang_item, [title]) item.setData(0, QtCore.Qt.UserRole, (filename, sha256)) item.setCheckState(0, QtCore.Qt.Unchecked) item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) self.bibles_tree_widget.expandAll() self.application.process_events() # Download the theme screenshots themes = self.config.get('themes', 'files').split(',') for theme in themes: title = self.config.get('theme_{theme}'.format(theme=theme), 'title') filename = self.config.get('theme_{theme}'.format(theme=theme), 'filename') sha256 = self.config.get('theme_{theme}'.format(theme=theme), 'sha256', fallback='') screenshot = self.config.get( 'theme_{theme}'.format(theme=theme), 'screenshot') worker = ThemeScreenshotWorker(self.themes_url, title, filename, sha256, screenshot) worker.screenshot_downloaded.connect( self.on_screenshot_downloaded) thread_name = 'theme_screenshot_{title}'.format(title=title) run_thread(worker, thread_name) self.theme_screenshot_threads.append(thread_name) self.application.process_events()