Exemplo n.º 1
0
    def test_get_installed_tethys_extensions_error(self, mock_harvester):
        # Mock the extension_modules variable with bad data
        mock_harvester().extension_modules = {'foo_invalid_foo': 'tethysext.foo_invalid_foo'}

        # Get a list of installed extensions
        result = helpers.get_installed_tethys_extensions()
        self.assertEqual({}, result)
Exemplo n.º 2
0
    def handle(self, *args, **options):
        """
        Symbolically link the static directories of each app into the static/public directory specified by the
        STATIC_ROOT parameter of the settings.py. Do this prior to running Django's collectstatic method.
        """  # noqa: E501
        if not settings.STATIC_ROOT:
            print(
                'WARNING: Cannot find the STATIC_ROOT setting. Please provide the path to the static directory using '
                'the STATIC_ROOT setting in the portal_config.yml file and try again.'
            )
            exit(1)

        # Read settings
        static_root = settings.STATIC_ROOT

        # Get a list of installed apps
        installed_apps_and_extensions = get_installed_tethys_apps()
        installed_apps_and_extensions.update(get_installed_tethys_extensions())

        # Provide feedback to user
        print(
            'INFO: Linking static and public directories of apps and extensions to "{0}".'
            .format(static_root))

        for item, path in installed_apps_and_extensions.items():
            # Check for both variants of the static directory (public and static)
            public_path = os.path.join(path, 'public')
            static_path = os.path.join(path, 'static')
            static_root_path = os.path.join(static_root, item)

            # Clear out old symbolic links/directories if necessary
            try:
                # Remove link
                os.remove(static_root_path)
            except OSError:
                try:
                    # Remove directory
                    shutil.rmtree(static_root_path)
                except OSError:
                    # No file
                    pass

            # Create appropriate symbolic link
            if os.path.isdir(public_path):
                os.symlink(public_path, static_root_path)
                print(
                    'INFO: Successfully linked public directory to STATIC_ROOT for app "{0}".'
                    .format(item))

            elif os.path.isdir(static_path):
                os.symlink(static_path, static_root_path)
                print(
                    'INFO: Successfully linked static directory to STATIC_ROOT for app "{0}".'
                    .format(item))
Exemplo n.º 3
0
def list_command(args):
    """
    List installed apps.
    """
    installed_apps = get_installed_tethys_apps()
    installed_extensions = get_installed_tethys_extensions()

    if installed_apps:
        print('Apps:')
        for item in installed_apps:
            print('  {}'.format(item))

    if installed_extensions:
        print('Extensions:')
        for item in installed_extensions:
            print('  {}'.format(item))
Exemplo n.º 4
0
    def handle(self, *args, **options):
        """
        Symbolically link the static directories of each app into the static/public directory specified by the STATIC_ROOT
        parameter of the settings.py. Do this prior to running Django's collectstatic method.
        """  # noqa: E501
        if not settings.STATIC_ROOT:
            print('WARNING: Cannot find the STATIC_ROOT setting in the settings.py file. '
                  'Please provide the path to the static directory using the STATIC_ROOT setting and try again.')
            exit(1)

        # Read settings
        static_root = settings.STATIC_ROOT

        # Get a list of installed apps
        installed_apps_and_extensions = get_installed_tethys_apps()
        installed_apps_and_extensions.update(get_installed_tethys_extensions())

        # Provide feedback to user
        print('INFO: Linking static and public directories of apps and extensions to "{0}".'.format(static_root))

        for item, path in installed_apps_and_extensions.items():
            # Check for both variants of the static directory (public and static)
            public_path = os.path.join(path, 'public')
            static_path = os.path.join(path, 'static')
            static_root_path = os.path.join(static_root, item)

            # Clear out old symbolic links/directories if necessary
            try:
                # Remove link
                os.remove(static_root_path)
            except OSError:
                try:
                    # Remove directory
                    shutil.rmtree(static_root_path)
                except OSError:
                    # No file
                    pass

            # Create appropriate symbolic link
            if os.path.isdir(public_path):
                os.symlink(public_path, static_root_path)
                print('INFO: Successfully linked public directory to STATIC_ROOT for app "{0}".'.format(item))

            elif os.path.isdir(static_path):
                os.symlink(static_path, static_root_path)
                print('INFO: Successfully linked static directory to STATIC_ROOT for app "{0}".'.format(item))
Exemplo n.º 5
0
    def handle(self, *args, **options):
        """
        Remove the app from disk and in the database
        """
        from tethys_apps.models import TethysApp, TethysExtension
        app_or_extension = "App" if not options['is_extension'] else 'Extension'
        PREFIX = 'tethysapp' if not options['is_extension'] else 'tethysext'
        item_name = options['app_or_extension'][0]

        # Check for app files installed
        installed_items = get_installed_tethys_extensions() if options['is_extension'] else get_installed_tethys_apps()

        if PREFIX in item_name:
            prefix_length = len(PREFIX) + 1
            item_name = item_name[prefix_length:]

        module_found = True
        if item_name not in installed_items:
            module_found = False

        # Check for app/extension in database
        TethysModel = TethysApp if not options['is_extension'] else TethysExtension
        db_app = None
        db_found = True

        try:
            db_app = TethysModel.objects.get(package=item_name)
        except TethysModel.DoesNotExist:
            db_found = False

        if not module_found and not db_found:
            warnings.warn('WARNING: {0} with name "{1}" cannot be uninstalled, because it is not installed or'
                          ' not an {0}.'.format(app_or_extension, item_name))
            exit(0)

        # Confirm
        item_with_prefix = '{0}-{1}'.format(PREFIX, item_name)

        valid_inputs = ('y', 'n', 'yes', 'no')
        no_inputs = ('n', 'no')

        overwrite_input = input('Are you sure you want to uninstall "{0}"? (y/n): '.format(item_with_prefix)).lower()

        while overwrite_input not in valid_inputs:
            overwrite_input = input('Invalid option. Are you sure you want to '
                                    'uninstall "{0}"? (y/n): '.format(item_with_prefix)).lower()

        if overwrite_input in no_inputs:
            self.stdout.write('Uninstall cancelled by user.')
            exit(0)

        # Remove app from database
        if db_found and db_app:
            db_app.delete()

        if module_found and not options['is_extension']:
            try:
                # Remove directory
                shutil.rmtree(installed_items[item_name])
            except OSError:
                # Remove symbolic link
                os.remove(installed_items[item_name])

        # Uninstall using pip
        process = ['pip', 'uninstall', '-y', '{0}-{1}'.format(PREFIX, item_name)]

        try:
            subprocess.Popen(process, stderr=subprocess.STDOUT, stdout=subprocess.PIPE).communicate()[0]
        except KeyboardInterrupt:
            pass

        # Remove the namespace package file if applicable.
        for site_package in site.getsitepackages():
            try:
                os.remove(os.path.join(site_package, "{}-{}-nspkg.pth".format(PREFIX, item_name.replace('_', '-'))))
            except Exception:
                continue

        self.stdout.write('{} "{}" successfully uninstalled.'.format(app_or_extension, item_with_prefix))
Exemplo n.º 6
0
    def handle(self, *args, **options):
        """
        Remove the app from disk and in the database
        """
        from tethys_apps.models import TethysApp, TethysExtension
        app_or_extension = "App" if not options['is_extension'] else 'Extension'
        PREFIX = 'tethysapp' if not options['is_extension'] else 'tethysext'
        item_name = options['app_or_extension'][0]

        # Check for app files installed
        installed_items = get_installed_tethys_extensions(
        ) if options['is_extension'] else get_installed_tethys_apps()

        if PREFIX in item_name:
            prefix_length = len(PREFIX) + 1
            item_name = item_name[prefix_length:]

        module_found = True
        if item_name not in installed_items:
            module_found = False

        # Check for app/extension in database
        TethysModel = TethysApp if not options[
            'is_extension'] else TethysExtension
        db_app = None
        db_found = True

        try:
            db_app = TethysModel.objects.get(package=item_name)
        except TethysModel.DoesNotExist:
            db_found = False

        if not module_found and not db_found:
            warnings.warn(
                'WARNING: {0} with name "{1}" cannot be uninstalled, because it is not installed or'
                ' not an {0}.'.format(app_or_extension, item_name))
            exit(0)

        # Confirm
        item_with_prefix = '{0}-{1}'.format(PREFIX, item_name)

        valid_inputs = ('y', 'n', 'yes', 'no')
        no_inputs = ('n', 'no')

        overwrite_input = input(
            'Are you sure you want to uninstall "{0}"? (y/n): '.format(
                item_with_prefix)).lower()

        while overwrite_input not in valid_inputs:
            overwrite_input = input(
                'Invalid option. Are you sure you want to '
                'uninstall "{0}"? (y/n): '.format(item_with_prefix)).lower()

        if overwrite_input in no_inputs:
            self.stdout.write('Uninstall cancelled by user.')
            exit(0)

        # Remove app from database
        if db_found and db_app:
            db_app.delete()

        if module_found and not options['is_extension']:
            try:
                # Remove directory
                shutil.rmtree(installed_items[item_name])
            except OSError:
                # Remove symbolic link
                os.remove(installed_items[item_name])

        # Uninstall using pip
        process = [
            'pip', 'uninstall', '-y', '{0}-{1}'.format(PREFIX, item_name)
        ]

        try:
            subprocess.Popen(process,
                             stderr=subprocess.STDOUT,
                             stdout=subprocess.PIPE).communicate()[0]
        except KeyboardInterrupt:
            pass

        # Remove the namespace package file if applicable.
        for site_package in site.getsitepackages():
            try:
                os.remove(
                    os.path.join(
                        site_package,
                        "{}-{}-nspkg.pth".format(PREFIX,
                                                 item_name.replace('_', '-'))))
            except Exception:
                continue

        self.stdout.write('{} "{}" successfully uninstalled.'.format(
            app_or_extension, item_with_prefix))
Exemplo n.º 7
0
 def test_get_installed_tethys_extensions(self):
     # Get a list of installed extensions
     result = helpers.get_installed_tethys_extensions()
     self.assertTrue('test_extension' in result)
Exemplo n.º 8
0
    def handle(self, *args, **kwargs):
        """
        Symbolically link the static directories of each app into the static/public directory specified by the
        STATIC_ROOT parameter of the settings.py. Do this prior to running Django's collectstatic method.
        """  # noqa: E501
        if not settings.STATIC_ROOT:
            print(
                'WARNING: Cannot find the STATIC_ROOT setting. Please provide the path to the static directory using '
                'the STATIC_ROOT setting in the portal_config.yml file and try again.'
            )
            exit(1)

        # Read settings
        static_root = settings.STATIC_ROOT

        # Get a list of installed apps and extensions
        installed_apps_and_extensions = get_installed_tethys_apps()
        installed_apps_and_extensions.update(get_installed_tethys_extensions())

        # Provide feedback to user
        print(
            'INFO: Collecting static and public directories of apps and extensions to "{0}".'
            .format(static_root))

        # Get the link option
        link_opt = kwargs.get('link')

        for item, path in installed_apps_and_extensions.items():
            # Check for both variants of the static directory (named either public or static)
            public_path = os.path.join(path, 'public')
            static_path = os.path.join(path, 'static')

            if os.path.isdir(public_path):
                item_static_source_dir = public_path
            elif os.path.isdir(static_path):
                item_static_source_dir = static_path
            else:
                print(
                    f'WARNING: Cannot find a directory named "static" or "public" for app "{item}". Skipping...'
                )
                continue

            # Path for app in the STATIC_ROOT directory
            item_static_root_dir = os.path.join(static_root, item)

            # Clear out old symbolic links/directories if necessary
            try:
                # Remove link
                os.remove(item_static_root_dir)
            except OSError:
                try:
                    # Remove directory
                    shutil.rmtree(item_static_root_dir)
                except OSError:
                    pass
                    # No file to remove

            # Create appropriate symbolic link
            if link_opt:
                os.symlink(item_static_source_dir, item_static_root_dir)
                print(
                    'INFO: Successfully linked public directory to STATIC_ROOT for app "{0}".'
                    .format(item))

            else:
                shutil.copytree(item_static_source_dir, item_static_root_dir)
                print(
                    'INFO: Successfully copied public directory to STATIC_ROOT for app "{0}".'
                    .format(item))