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)
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))
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))
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))
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))
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))
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)
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))