From f0686a43cb668c85db657867eb87215c3da330e0 Mon Sep 17 00:00:00 2001 From: Jeremy Weinstein Date: Sun, 15 Aug 2021 16:35:35 -0700 Subject: [PATCH] refactor!: remove management commands (use pipenv instead) --- grow/commands/__init__.py | 4 - grow/commands/subcommands/init.py | 27 ---- grow/commands/subcommands/upgrade.py | 27 ---- grow/common/utils_test.py | 9 -- grow/pods/pods.py | 11 -- grow/sdk/themes.py | 55 ------- grow/sdk/themes_test.py | 56 ------- grow/sdk/updater.py | 162 ------------------- grow/sdk/updater_test.py | 231 --------------------------- grow/server/manager.py | 7 - 10 files changed, 589 deletions(-) delete mode 100644 grow/commands/subcommands/init.py delete mode 100644 grow/commands/subcommands/upgrade.py delete mode 100644 grow/sdk/themes.py delete mode 100644 grow/sdk/themes_test.py delete mode 100644 grow/sdk/updater.py delete mode 100644 grow/sdk/updater_test.py diff --git a/grow/commands/__init__.py b/grow/commands/__init__.py index 1ff9541e0..a8466d5ba 100644 --- a/grow/commands/__init__.py +++ b/grow/commands/__init__.py @@ -3,14 +3,12 @@ from grow.commands.subcommands import build from grow.commands.subcommands import convert from grow.commands.subcommands import deploy -from grow.commands.subcommands import init from grow.commands.subcommands import inspect from grow.commands.subcommands import install from grow.commands.subcommands import preprocess from grow.commands.subcommands import run from grow.commands.subcommands import stage from grow.commands.subcommands import translations -from grow.commands.subcommands import upgrade def add_subcommands(group): @@ -18,11 +16,9 @@ def add_subcommands(group): group.add_command(build.build) group.add_command(convert.convert) group.add_command(deploy.deploy) - group.add_command(init.init) group.add_command(inspect.inspect) group.add_command(install.install) group.add_command(preprocess.preprocess) group.add_command(run.run) group.add_command(stage.stage) group.add_command(translations.translations) - group.add_command(upgrade.upgrade) diff --git a/grow/commands/subcommands/init.py b/grow/commands/subcommands/init.py deleted file mode 100644 index e1c807348..000000000 --- a/grow/commands/subcommands/init.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Subcommand to initialize a new pod.""" - -import os -import click -from grow.commands import shared -from grow.common import rc_config -from grow.pods import pods -from grow import storage -from grow.sdk import themes - - -CFG = rc_config.RC_CONFIG.prefixed('grow.init') - - -@click.command() -@click.argument('theme') -@shared.pod_path_argument -@click.option('--force', default=False, is_flag=True, - help='Whether to overwrite existing files.') -def init(theme, pod_path, force): - """Initializes a pod with a theme.""" - root = os.path.abspath(os.path.join(os.getcwd(), pod_path)) - pod = pods.Pod(root, storage=storage.FileStorage) - with pod.profile.timer('grow_init'): - theme = themes.GrowTheme(theme) - theme.extract(pod, force=force) - return pod diff --git a/grow/commands/subcommands/upgrade.py b/grow/commands/subcommands/upgrade.py deleted file mode 100644 index cad5d55bb..000000000 --- a/grow/commands/subcommands/upgrade.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Subcommand for upgrading grow.""" - -import os -import click -from grow.commands import shared -from grow.pods import pods -from grow.sdk import sdk_utils -from grow.sdk import updater -from grow import storage - - -@click.command() -@shared.pod_path_argument -def upgrade(pod_path): - """Check for and upgrade grow when available.""" - root = os.path.abspath(os.path.join(os.getcwd(), pod_path)) - try: - pod = pods.Pod(root, storage=storage.FileStorage) - with pod.profile.timer('grow_upgrade'): - pod.logger.info('Checking for newer versions of grow.') - update_checker = updater.Updater(pod) - if not update_checker.check_for_updates(force=True): - pod.logger.info( - 'No updates found. Running Grow v{}'.format(sdk_utils.VERSION)) - except pods.Error as err: - raise click.ClickException(str(err)) - return pod diff --git a/grow/common/utils_test.py b/grow/common/utils_test.py index ed468d7d8..a702b8eff 100644 --- a/grow/common/utils_test.py +++ b/grow/common/utils_test.py @@ -6,7 +6,6 @@ import semantic_version from grow.testing import testing from grow.sdk import sdk_utils -from grow.sdk import updater from grow.pods import errors from . import utils @@ -225,14 +224,6 @@ def test_validate_name(self): utils.validate_name('./you/shall/pass') utils.validate_name('\xbe4/\xb05/\xb93') - def test_version_enforcement(self): - with mock.patch('grow.pods.pods.Pod.grow_version', - new_callable=mock.PropertyMock) as mock_version: - gt_version = '>{0}'.format(semantic_version.Version(sdk_utils.VERSION)) - mock_version.return_value = gt_version - with self.assertRaises(updater.LatestVersionCheckError): - _ = testing.create_test_pod() - def test_walk(self): data = { 'foo': 'bar', diff --git a/grow/pods/pods.py b/grow/pods/pods.py index b4d6445ff..2940181cd 100644 --- a/grow/pods/pods.py +++ b/grow/pods/pods.py @@ -23,8 +23,6 @@ from grow.common import progressbar_non from grow.common import untag from grow.common import utils -from grow.documents import document -from grow.documents import document_fields from grow.documents import static_document from grow.extensions import extension_controller as ext_controller from grow.extensions import extension_importer @@ -39,7 +37,6 @@ from grow.routing import path_filter as grow_path_filter from grow.routing import path_format as grow_path_format from grow.routing import router as grow_router -from grow.sdk import updater from grow.templates import filters from grow.templates import jinja_dependency from grow.templates import tags @@ -48,7 +45,6 @@ from grow.translations import translation_stats from grow.translators import translators from . import env as environment -from . import messages from . import podspec @@ -134,13 +130,6 @@ def __init__(self, root, storage=grow_storage.AUTO, env=None, load_extensions=Tr # Load extensions, ignore local extensions during install. self._load_extensions(load_extensions) - - try: - update_checker = updater.Updater(self) - update_checker.verify_required_version() - except PodDoesNotExistError: - pass # Pod doesn't exist yet, simply pass. - def __ne__(self, other): return not self.__eq__(other) diff --git a/grow/sdk/themes.py b/grow/sdk/themes.py deleted file mode 100644 index c7db4abc9..000000000 --- a/grow/sdk/themes.py +++ /dev/null @@ -1,55 +0,0 @@ -"""Grow theme management.""" - -import io -import logging -import zipfile -import requests - -THEME_ARCHIVE_URL = 'https://github.com/growthemes/{}/archive/master.zip' - - -class GrowTheme(object): - """Grow theme.""" - - def __init__(self, theme_name): - self.theme_name = theme_name - self.archive_url = THEME_ARCHIVE_URL.format(self.theme_name) - - @property - def archive(self): - """Download the archive zip and open.""" - logging.info('Downloading `{}` from Github'.format(self.theme_name)) - request = requests.get(self.archive_url) - return zipfile.ZipFile(io.BytesIO(request.content), 'r') - - def extract(self, pod, force=False): - """Extract the source archive into the destination pod.""" - with self.archive as archive: - logging.info('Extracting theme into {}'.format(pod.root)) - - # Automatically enable "force" for empty directories. - if pod.list_dir('/') == []: - force = True - - archive_prefix_dir = '{}-master'.format(self.theme_name) - archive_files = [name[len(archive_prefix_dir):] for name in archive.namelist()] - - # Validate that it won't overwrite any files. - if not force: - for file_name in archive_files: - if file_name == '/': - continue - if pod.file_exists(file_name): - text = ('{}{} already exists. Delete the directory contents before' - ' proceeding or use --force.') - logging.warn(text.format(pod.root, file_name)) - return - - for file_name in archive_files: - if file_name.endswith('/'): - continue - - pod.write_file( - file_name, archive.read('{}{}'.format(archive_prefix_dir, file_name))) - - logging.info('Pod ready to go: {}'.format(pod.root)) diff --git a/grow/sdk/themes_test.py b/grow/sdk/themes_test.py deleted file mode 100644 index 5842b199f..000000000 --- a/grow/sdk/themes_test.py +++ /dev/null @@ -1,56 +0,0 @@ -"""Tests for Themes.""" - -import os -import unittest -import zipfile -import mock -from grow.sdk import themes -from grow.testing import testing - - -TEST_ZIP_FILE = os.path.abspath( - os.path.join( - os.path.dirname(__file__), '..', 'testing', 'testdata', 'themes', 'base-master.zip')) - - -class ThemesTestCase(unittest.TestCase): - """Test the Themes.""" - - def setUp(self): - self.pod = testing.create_pod() - - @mock.patch('grow.sdk.themes.GrowTheme.archive', - new_callable=mock.PropertyMock) - def test_extract(self, mock_archive): - """Test theme unpacking.""" - mock_archive.return_value = zipfile.ZipFile(TEST_ZIP_FILE, 'r') - self.assertFalse(self.pod.file_exists('/podspec.yaml')) - theme = themes.GrowTheme('base') - theme.extract(self.pod) - self.assertTrue(self.pod.file_exists('/podspec.yaml')) - - @mock.patch('grow.sdk.themes.GrowTheme.archive', - new_callable=mock.PropertyMock) - def test_extract_existing(self, mock_archive): - """Test theme unpacking.""" - mock_archive.return_value = zipfile.ZipFile(TEST_ZIP_FILE, 'r') - self.assertFalse(self.pod.file_exists('/gulpfile.js')) - self.assertFalse(self.pod.file_exists('/podspec.yaml')) - self.pod.write_file('/podspec.yaml', '') - self.assertTrue(self.pod.file_exists('/podspec.yaml')) - theme = themes.GrowTheme('base') - theme.extract(self.pod) - self.assertFalse(self.pod.file_exists('/gulpfile.js')) - - @mock.patch('grow.sdk.themes.GrowTheme.archive', - new_callable=mock.PropertyMock) - def test_extract_force(self, mock_archive): - """Test theme unpacking.""" - mock_archive.return_value = zipfile.ZipFile(TEST_ZIP_FILE, 'r') - self.assertFalse(self.pod.file_exists('/gulpfile.js')) - self.assertFalse(self.pod.file_exists('/podspec.yaml')) - self.pod.write_file('/podspec.yaml', '') - self.assertTrue(self.pod.file_exists('/podspec.yaml')) - theme = themes.GrowTheme('base') - theme.extract(self.pod, force=True) - self.assertTrue(self.pod.file_exists('/gulpfile.js')) diff --git a/grow/sdk/updater.py b/grow/sdk/updater.py deleted file mode 100644 index 37cb1262d..000000000 --- a/grow/sdk/updater.py +++ /dev/null @@ -1,162 +0,0 @@ -# coding: utf8 -"""Grow update class.""" - -import logging -import os -import subprocess -import sys -import requests -import semantic_version -from grow.common import colors -from grow.common import rc_config -from grow.common import utils -from grow.sdk import sdk_utils - - -RELEASES_API = 'https://api.github.com/repos/grow/grow/releases' -TAGS_URL_FORMAT = 'https://github.com/grow/grow/releases/tag/{}' -INSTALLER_COMMAND = 'pipenv install grow=={version}' - - -class Error(Exception): - """Base error for updaters.""" - - def __init__(self, message): - super(Error, self).__init__(message) - self.message = message - - -class LatestVersionCheckError(Error): - """Error checking for the latest version.""" - pass - - -class Updater(object): - """Grow updater for dependencies.""" - - def __init__(self, pod): - self.pod = pod - - @property - def current_version(self): - """Current version of grow.""" - return sdk_utils.VERSION - - @utils.cached_property - def latest_version(self): # pylint: disable=no-self-use - """Latest version available for current platform.""" - try: - releases = requests.get(RELEASES_API).json() - if 'message' in releases: - text = 'Error while downloading release information: {}'.format( - releases['message']) - logging.error(colors.stylize(text, colors.ERROR)) - raise LatestVersionCheckError(str(text)) - for release in releases: - if release['prerelease']: - continue - for each_asset in release['assets']: - if sdk_utils.PLATFORM in each_asset.get('name', '').lower(): - return release['tag_name'] - raise LatestVersionCheckError( - 'Unable to find a release for {} platform.'.format(sdk_utils.PLATFORM)) - except LatestVersionCheckError: - raise - except Exception as err: - logging.exception(colors.stylize(str(err), colors.ERROR)) - text = 'Unable to check for the latest version: {}'.format(str(err)) - logging.error(colors.stylize(text, colors.ERROR)) - raise LatestVersionCheckError(str(err)) - - def check_for_updates(self, auto_update_prompt=False, force=False): - """Check for updates to the sdk.""" - grow_rc_config = rc_config.RC_CONFIG - - # Rate limited update checks. - if not grow_rc_config.needs_update_check and not force: - return - - try: - sem_current = semantic_version.Version(self.current_version) - sem_latest = semantic_version.Version(self.latest_version) - # Mark that we have performed a check for the update. - grow_rc_config.reset_update_check() - grow_rc_config.write() - except LatestVersionCheckError: - return - - if sem_latest <= sem_current: - return - - url = TAGS_URL_FORMAT.format(self.latest_version) - - if sem_latest.major > sem_current.major: - logging.info('') - logging.info(' A new major version of Grow.dev is available.') - logging.info(' Major version changes can be backwards incompatible.') - logging.info(' Please check the release notes for upgrade instructions.') - logging.info(' Release notes: {}'.format(url)) - logging.info(' Your version: {}, latest version: {}'.format( - colors.stylize(str(sem_current), colors.EMPHASIS), - colors.stylize(str(sem_latest), colors.EMPHASIS))) - return - - logging.info('') - logging.info(' Please update to the newest version of Grow.dev.') - logging.info(' Release notes: {}'.format(url)) - logging.info(' Your version: {}, latest version: {}'.format( - colors.stylize(str(sem_current), colors.EMPHASIS), - colors.stylize(str(sem_latest), colors.EMPHASIS))) - - install_command = INSTALLER_COMMAND.format(version=sem_latest) - if auto_update_prompt: - use_auto_update = grow_rc_config.get('update.always', False) - - if use_auto_update: - logging.info(' > Auto-updating to version: {}'.format( - colors.stylize(str(sem_latest), colors.HIGHLIGHT))) - else: # pragma: no cover - try: - choice = input( - 'Auto update now? [Y]es / [n]o / [a]lways: ').strip().lower() - except KeyboardInterrupt: - choice = 'n' - if choice not in ('y', 'a', ''): - return - if choice == 'a': - grow_rc_config.set('update.always', True) - grow_rc_config.write() - - if subprocess.call((install_command), shell=True) == 0: - logging.info('Restarting...') - try: - # Restart on successful install. - os.execl(sys.argv[0], *sys.argv) - except OSError: - logging.info( - 'Unable to restart. Please manually restart grow.') - sys.exit(-1) - else: - text = 'In-place update failed. Update manually or use:\n {}' - logging.error(text.format(install_command)) - sys.exit(-1) - else: - logging.info(' Update using: {}'.format(install_command)) - logging.info('') - return True - - def verify_required_version(self): - """Verify that the required version for the pod is met.""" - if self.pod.grow_version is None: - return - sem_current = semantic_version.Version(self.current_version) - grow_version_pattern = '{}'.format(self.pod.grow_version) - # Include pre-releases in the version check. - if '-' not in grow_version_pattern: - grow_version_pattern = '{}-'.format(grow_version_pattern) - spec_required = semantic_version.SimpleSpec(grow_version_pattern) - if sem_current not in spec_required: - text = 'ERROR! Pod requires Grow.dev version: {}'.format( - self.pod.grow_version) - logging.error(colors.stylize(text, colors.ERROR)) - raise LatestVersionCheckError(text) diff --git a/grow/sdk/updater_test.py b/grow/sdk/updater_test.py deleted file mode 100644 index 0d4563f47..000000000 --- a/grow/sdk/updater_test.py +++ /dev/null @@ -1,231 +0,0 @@ -"""Tests for SDK Updater.""" - -import unittest -import mock -from grow.pods import pods -from grow import storage -from grow.sdk import updater -from grow.testing import testing - - -class UpdaterTestCase(unittest.TestCase): - """Test the SDK Updater.""" - - @staticmethod - def _mock_json(mock_get, response): - mock_json = mock.Mock(return_value=response) - mock_get_result = mock.Mock() - mock_get_result.json = mock_json - mock_get.return_value = mock_get_result - - def setUp(self): - self.dir_path = testing.create_test_pod_dir() - self.pod = pods.Pod(self.dir_path, storage=storage.FileStorage) - self.updater = updater.Updater(self.pod) - - @mock.patch('grow.common.rc_config.RC_CONFIG') - @mock.patch('grow.sdk.updater.Updater.current_version', - new_callable=mock.PropertyMock) - @mock.patch('grow.sdk.updater.Updater.latest_version', - new_callable=mock.PropertyMock) - def test_check_for_updates(self, mock_latest_version, mock_current_version, mock_config): - """Update check works.""" - mock_config.needs_update_check = True - mock_latest_version.return_value = '0.1.1' - mock_current_version.return_value = '0.1.0' - self.updater.check_for_updates() - mock_config.write.assert_called() - - @mock.patch('os.execl') - @mock.patch('subprocess.call') - @mock.patch('grow.common.rc_config.RC_CONFIG') - @mock.patch('grow.sdk.updater.Updater.current_version', - new_callable=mock.PropertyMock) - @mock.patch('grow.sdk.updater.Updater.latest_version', - new_callable=mock.PropertyMock) - def test_check_for_updates_packaged_app(self, mock_latest_version, mock_current_version, - mock_config, mock_subprocess_call, mock_os_execl): - """Update check works on packaged app.""" - mock_config.needs_update_check = True - mock_latest_version.return_value = '0.1.1' - mock_current_version.return_value = '0.1.0' - mock_config.get.return_value = True - mock_subprocess_call.return_value = 0 - mock_os_execl.return_value = True - self.updater.check_for_updates(auto_update_prompt=True) - mock_config.write.assert_called() - - @mock.patch('os.execl') - @mock.patch('subprocess.call') - @mock.patch('grow.common.rc_config.RC_CONFIG') - @mock.patch('grow.sdk.updater.Updater.current_version', - new_callable=mock.PropertyMock) - @mock.patch('grow.sdk.updater.Updater.latest_version', - new_callable=mock.PropertyMock) - def test_check_for_updates_packaged_app_restart_fail( - self, mock_latest_version, mock_current_version, mock_config, - mock_subprocess_call, mock_os_execl): - """Update check fails when error restarting.""" - mock_config.needs_update_check = True - mock_latest_version.return_value = '0.1.1' - mock_current_version.return_value = '0.1.0' - mock_config.get.return_value = True - mock_subprocess_call.return_value = 0 - mock_os_execl.side_effect = OSError() - with self.assertRaises(SystemExit): - self.updater.check_for_updates(auto_update_prompt=True) - mock_config.write.assert_called() - - @mock.patch('os.execl') - @mock.patch('subprocess.call') - @mock.patch('grow.common.rc_config.RC_CONFIG') - @mock.patch('grow.sdk.updater.Updater.current_version', - new_callable=mock.PropertyMock) - @mock.patch('grow.sdk.updater.Updater.latest_version', - new_callable=mock.PropertyMock) - def test_check_for_updates_packaged_app_fail(self, mock_latest_version, mock_current_version, - mock_config, mock_subprocess_call, _mock_os_execl): - """Update check fails when install fails.""" - mock_config.needs_update_check = True - mock_latest_version.return_value = '0.1.1' - mock_current_version.return_value = '0.1.0' - mock_config.get.return_value = True - mock_subprocess_call.return_value = 1 - with self.assertRaises(SystemExit): - self.updater.check_for_updates(auto_update_prompt=True) - mock_config.write.assert_called() - - @mock.patch('os.execl') - @mock.patch('subprocess.call') - @mock.patch('grow.common.rc_config.RC_CONFIG') - @mock.patch('grow.sdk.updater.Updater.current_version', - new_callable=mock.PropertyMock) - @mock.patch('grow.sdk.updater.Updater.latest_version', - new_callable=mock.PropertyMock) - def test_check_for_updates_no_update(self, mock_latest_version, mock_current_version, - mock_config, mock_subprocess_call, mock_os_execl): - """Update check works when no need to update.""" - mock_config.needs_update_check = True - mock_latest_version.return_value = '0.1.0' - mock_current_version.return_value = '0.1.0' - mock_subprocess_call.return_value = 0 - mock_os_execl.return_value = True - self.updater.check_for_updates(auto_update_prompt=True) - mock_config.write.assert_called() - - @mock.patch('os.execl') - @mock.patch('subprocess.call') - @mock.patch('grow.common.rc_config.RC_CONFIG') - @mock.patch('grow.sdk.updater.Updater.current_version', - new_callable=mock.PropertyMock) - @mock.patch('grow.sdk.updater.Updater.latest_version', - new_callable=mock.PropertyMock) - def test_check_for_updates_latest_fail(self, mock_latest_version, mock_current_version, - mock_config, mock_subprocess_call, mock_os_execl): - """Update check works when cannot get latest version.""" - mock_config.needs_update_check = True - mock_latest_version.side_effect = updater.LatestVersionCheckError('Update fail') - mock_current_version.return_value = '0.1.0' - mock_subprocess_call.return_value = 0 - mock_os_execl.return_value = True - self.updater.check_for_updates(auto_update_prompt=True) - - @mock.patch('os.execl') - @mock.patch('subprocess.call') - @mock.patch('grow.common.rc_config.RC_CONFIG') - def test_check_for_updates_no_need(self, mock_config, mock_subprocess_call, - mock_os_execl): - """Update check is skipped for rate limiting.""" - mock_config.needs_update_check = False - mock_config.get.return_value = True - mock_subprocess_call.return_value = 0 - mock_os_execl.return_value = True - self.updater.check_for_updates(auto_update_prompt=True) - - @mock.patch('requests.get') - def test_latest_version_normal(self, mock_get): - """Latest version check works.""" - self._mock_json(mock_get, [ - { - 'prerelease': False, - 'tag_name': '0.3.20', - 'assets': [ - { - 'name': 'Grow-SDK-Mac-0.3.20.zip', - }, - { - 'name': 'Grow-SDK-Linux-0.3.20.zip', - }, - ], - }, - ]) - self.assertEqual('0.3.20', self.updater.latest_version) - - @mock.patch('requests.get') - def test_latest_version_prerelease(self, mock_get): - """Latest version check ignores prereleases.""" - self._mock_json(mock_get, [ - { - 'prerelease': True, - 'tag_name': '0.3.20', - 'assets': [ - { - 'name': 'Grow-SDK-Mac-0.3.20.zip', - }, - { - 'name': 'Grow-SDK-Linux-0.3.20.zip', - }, - ], - }, - { - 'prerelease': False, - 'tag_name': '0.3.19', - 'assets': [ - { - 'name': 'Grow-SDK-Mac-0.3.19.zip', - }, - { - 'name': 'Grow-SDK-Linux-0.3.19.zip', - }, - ], - }, - ]) - # Ignores prerelease - self.assertEqual('0.3.19', self.updater.latest_version) - - @mock.patch('requests.get') - def test_latest_version_missing(self, mock_get): - """Latest version check fails when missing a valid platform asset.""" - self._mock_json(mock_get, [ - { - 'prerelease': False, - 'tag_name': '0.3.20', - 'assets': [ - { - 'name': 'Grow-SDK-Pear-0.3.20.zip', - }, - { - 'name': 'Grow-SDK-Unix-0.3.20.zip', - }, - ], - }, - ]) - # Missing platform throws an error - with self.assertRaises(updater.LatestVersionCheckError): - _ = self.updater.latest_version - - @mock.patch('requests.get') - def test_latest_version_message(self, mock_get): - """Latest version check fails when a message is present in response.""" - self._mock_json(mock_get, { - 'message': 'Test' - }) - with self.assertRaises(updater.LatestVersionCheckError): - _ = self.updater.latest_version - - @mock.patch('requests.get') - def test_latest_version_error(self, mock_get): - """Latest version check fails on exception.""" - mock_get.side_effect = Exception('Testing') - with self.assertRaises(updater.LatestVersionCheckError): - _ = self.updater.latest_version diff --git a/grow/server/manager.py b/grow/server/manager.py index 0ea8951ab..1be1be300 100644 --- a/grow/server/manager.py +++ b/grow/server/manager.py @@ -10,7 +10,6 @@ from grow.common import timer from grow.documents import document from grow.preprocessors import file_watchers -from grow.sdk import updater from grow.server import main as main_lib from werkzeug import serving @@ -39,12 +38,6 @@ def server_activate(self): start_browser_in_thread(url) for extra_url in extra_urls: start_browser_in_thread(extra_url) - if self.update_check: - update_checker = updater.Updater(self.pod) - check_func = update_checker.check_for_updates - thread = threading.Thread(target=check_func, args=(True,)) - thread.start() - class ServerMessages: """Simple server messages."""