Example #1
0
    def __init__(self, command=None, return_url=None, restart=False):
        self.command = command
        self.terminal_id = prism.generate_random_string(8)
        self.return_url = return_url
        self.restart = restart
        self.process = TerminalProcess(*pty.openpty())

        logging.info('Terminal Opened: %s' % self.terminal_id)
Example #2
0
def ping_version(output=False):
	global PRISM_VERSIONING

	should_check = True
	if 'last_check' in PRISM_VERSIONING:
		should_check = ((datetime.now() - datetime.strptime(PRISM_VERSIONING['last_check'], "%Y-%m-%d %H:%M:%S")).seconds >= 60 * 60 * 2)

	if output or should_check:
		logging.up('Collecting version info...')

	if should_check:
		rate_limited, dev_changes, recent_releases, num_releases = get_new_versions(prism.__version__)

		if rate_limited:
			logging.error('Rate limited. Version info not checked.')

			# If no values made yet, apply some defaults
			if 'dev_changes' not in PRISM_VERSIONING:
				PRISM_VERSIONING['dev_changes'] = []
			if 'recent_releases' not in PRISM_VERSIONING:
				PRISM_VERSIONING['recent_releases'] = []
			if 'num_releases' not in PRISM_VERSIONING:
				PRISM_VERSIONING['num_releases'] = 0
		else:
			# Reset and reapply cached versioning info
			PRISM_VERSIONING['dev_changes'] = []
			PRISM_VERSIONING['recent_releases'] = []
			PRISM_VERSIONING['num_releases'] = 0

			if 'dev_changes' is not None:
				PRISM_VERSIONING['dev_changes'] = dev_changes
			if 'recent_releases' is not None:
				PRISM_VERSIONING['recent_releases'] = recent_releases
			if 'num_releases' is not None:
				PRISM_VERSIONING['num_releases'] = num_releases

			if 'dev_changes' is not None or 'recent_releases' is not None or 'num_releases' is not None:
				PRISM_VERSIONING['last_check'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

	if output or should_check:
		if PRISM_VERSIONING['dev_changes'] is None:
			logging.error('Failed to check development version.')
		elif len(PRISM_VERSIONING['dev_changes']) > 0:
			logging.info('%s development commit(s) since the latest version.' % len(PRISM_VERSIONING['dev_changes']))
		if PRISM_VERSIONING['recent_releases'] is None:
			logging.error('Failed to check for latest version.')
		elif len(PRISM_VERSIONING['recent_releases']) != 0:
			logging.info('Current version: %s' % prism.__version__)
			if prism.__version__ != PRISM_VERSIONING['recent_releases'][0]['name']:
				logging.error('Your version is out of date. Latest version is %s' % PRISM_VERSIONING['recent_releases'][0]['name'])
			logging.down()
		logging.down()
Example #3
0
    def _search_plugins(self, path, is_core):
        """ Searches for plugins in a specified folder """
        if is_core:
            logging.info('Finding core plugins')
        else:
            logging.info('Finding additional plugins')

        sys.path.append(path)

        for plugin_id in os.listdir(path):
            if not plugin_id.startswith('prism_'):
                continue

            base_folder = os.path.join(path, plugin_id)
            if not os.path.isfile(base_folder):
                if not os.path.exists(os.path.join(base_folder,
                                                   'plugin.json')):
                    logging.error(
                        'Plugin does not have a plugin.json file. Offender: %s'
                        % plugin_id)
                    continue

                plugin_info = JSONConfig(base_folder,
                                         'plugin.json',
                                         auto_save=False)
                plugin_info['_id'] = plugin_id
                plugin_info['id'] = plugin_info['_id'].split('_', 1)[1]
                plugin_info['_is_core'] = is_core
                plugin_info['_is_satisfied'] = True
                plugin_info['_is_enabled'] = False

                # Make the version readable
                version = None
                for i in plugin_info['version']:
                    if isinstance(i, int):
                        if version is None:
                            version = str(i)
                        else:
                            version += '.' + str(i)
                    else:
                        version += '-' + i
                plugin_info['_version'] = plugin_info['version']
                plugin_info['version'] = version

                plugin_info['_dependencies'] = list()

                self.available_plugins[plugin_id] = plugin_info
Example #4
0
def init(pid):
	global PANEL_PID, PRISM_PATH, TMP_PATH, PRISM_VERSIONING, CORE_PLUGINS_PATH, \
			PLUGINS_PATH, CONFIG_FOLDER_PLUGINS, CONFIG_FOLDER, PRISM_CONFIG, PRISM_LOCALE

	PANEL_PID = pid
	PRISM_PATH = os.path.dirname(os.path.realpath(__file__))

	CORE_PLUGINS_PATH = os.path.join(PRISM_PATH, 'core')
	if not os.path.exists(CORE_PLUGINS_PATH):
		os.makedirs(CORE_PLUGINS_PATH)

	PLUGINS_PATH = os.path.join(PRISM_PATH, 'plugins')
	if not os.path.exists(PLUGINS_PATH):
		os.makedirs(PLUGINS_PATH)

	TMP_PATH = os.path.join(PRISM_PATH, 'tmp')
	if not os.path.exists(TMP_PATH):
		os.makedirs(TMP_PATH)

	logging.info('Currently running in %s' % PRISM_PATH)
	logging.output()

	PRISM_VERSIONING = JSONConfig(path=os.path.join(TMP_PATH, 'VERSIONING-INFO'))

	# Load Prism's config
	CONFIG_FOLDER = os.path.join(PRISM_PATH, 'config')
	if not os.path.exists(CONFIG_FOLDER):
		os.makedirs(CONFIG_FOLDER)
	config_file = os.path.join(CONFIG_FOLDER, 'config.json')

	CONFIG_FOLDER_PLUGINS = os.path.join(CONFIG_FOLDER, 'plugins')
	if not os.path.exists(CONFIG_FOLDER_PLUGINS):
		os.makedirs(CONFIG_FOLDER_PLUGINS)

	PRISM_LOCALE = LocaleConfig(PRISM_PATH)

	# Generate default config values if the file doesn't exist
	# Also, prompt and generate a few of the config values that
	# must be done on first run.
	if not os.path.exists(config_file):
		# I have no idea what came over me when making this section,
		# but it's fabulous and I loved every second of it. I hope
		# I never have to change it. xD
		logging.output(PRISM_LOCALE['start.hello.1'])
		logging.output(PRISM_LOCALE['start.hello.2'])
		subst = {}

		# IP Address/Hostname prompt
		subst['host'] = socket.gethostbyname(socket.gethostname())
		logging.output(PRISM_LOCALE['start.host'].format(**subst))
		PRISM_CONFIG['host'], used_default = prism.get_input(PRISM_LOCALE['start.host.prompt'], default=subst['host'])

		if used_default:
			logging.output()
			logging.output(PRISM_LOCALE['start.host.correct'])

		# Secret generation
		logging.output()
		logging.output(PRISM_LOCALE['start.secret'])
		subst['secret_key'], used_default = prism.get_input(PRISM_LOCALE['start.secret.prompt'])

		logging.output()
		if used_default:
			subst['secret_key'] = prism.generate_random_string(32)
			logging.output(PRISM_LOCALE['start.secret.generate'].format(**subst))
		else:
			logging.output(PRISM_LOCALE['start.secret.done'].format(**subst))

		PRISM_CONFIG['secret_key'] = subst['secret_key']

		# Dev check
		logging.output()
		logging.output(PRISM_LOCALE['start.dev_mode'])
		PRISM_CONFIG['dev_mode'] = prism.get_yesno(PRISM_LOCALE['start.dev_mode.prompt'])

		logging.output()
		logging.output(PRISM_LOCALE['start.done'])
		logging.output()

		conf = JSONConfig(path=config_file)
		for key, value in PRISM_CONFIG.items():
			conf[key] = value
		PRISM_CONFIG = conf
	else:
		# Load prism's config
		PRISM_CONFIG = JSONConfig(path=config_file)

		if 'locale' not in PRISM_CONFIG:
			PRISM_CONFIG['locale'] = 'en_US'

		if 'enabled_plugins' not in PRISM_CONFIG:
			PRISM_CONFIG['enabled_plugins'] = [F]

		# Make sure some VERY imporant values are set
		if 'secret_key' not in PRISM_CONFIG:
			logging.output(PRISM_LOCALE['start.missing.secret'])
			PRISM_CONFIG['secret_key'] = prism.generate_random_string(32)
			logging.output()

		if 'host' not in PRISM_CONFIG:
			host = socket.gethostbyname(socket.gethostname())
			logging.output(PRISM_LOCALE['start.missing.host'])
			PRISM_CONFIG['host'], used_default = prism.get_input(PRISM_LOCALE['start.host.prompt'], default=host)
			logging.output()
Example #5
0
    def _init_plugin(self, plugin):
        """
		Initializes a plugin:
			1. Runs the plugin's init() function.
			2. Saves the config
			3. Loads the plugin's endpoints into flask
		"""
        logging.up('Starting %s v%s' % (plugin.name, plugin.version))

        def get_wrapper(plugin):
            def func():
                return plugin

            return func

        setattr(plugin.__class__, 'get', get_wrapper(plugin))

        plugin.init(PRISM_STATE)
        plugin.config.save()

        blueprint_name = plugin._endpoint
        # Create the plugin blueprint in flask
        plugin._blueprint = Blueprint(blueprint_name,
                                      plugin._info['_id'],
                                      template_folder='templates')

        if len(plugin._module_views) > 0:
            self.possible_permissions[plugin.plugin_id] = {}

            # Go through each of the module's views and add them to flask
            for view_class in plugin._module_views:
                view = view_class()

                self.possible_permissions[plugin.plugin_id][str(
                    view_class.__name__)] = view.title

                endpoint_id = '%s' % view_class.__name__

                with flask_app().app_context():
                    if view.menu is not None:
                        # Generate the parent menu item
                        if 'parent' in view.menu:
                            if '.' not in view.menu['parent']['id']:
                                parts = ('/' + blueprint_name +
                                         view.endpoint).split('/')
                                flask_app().add_url_rule(
                                    '/'.join(parts[:-1]),
                                    endpoint=blueprint_name + '.' +
                                    view.menu['parent']['id'])
                                item = current_menu.submenu(
                                    view.menu['parent']['id'])
                                item.register(blueprint_name + '.' +
                                              view.menu['parent']['id'],
                                              view.menu['parent']['text'],
                                              view.menu['parent']['order'],
                                              icon=view.menu['parent']['icon'])
                            else:
                                item = current_menu.submenu(
                                    view.menu['parent']['id'])
                                item.register(blueprint_name + '.' +
                                              endpoint_id,
                                              view.menu['parent']['text'],
                                              view.menu['parent']['order'],
                                              icon=view.menu['parent']['icon'])
                        item = current_menu.submenu(view.menu['id'])
                        item.register(blueprint_name + '.' + endpoint_id,
                                      view.title,
                                      view.menu['order'],
                                      icon=view.menu['icon'])
                        if prism.settings.is_dev():
                            logging.info('Registered menu item for /%s: %s' %
                                         (blueprint_name + view.endpoint,
                                          view.menu['id']))
                    else:
                        # Generate a hidden menu item so titles show correctly
                        item = current_menu.submenu(generate_random_string(12))
                        item.register(blueprint_name + '.' + endpoint_id,
                                      view.title,
                                      hidden=True)

                # Find all methods in the view class
                for func_name in [
                        method for method in dir(view)
                        if callable(getattr(view, method))
                ]:
                    if func_name.startswith('_'):
                        continue

                    if func_name not in ['get', 'post', 'put', 'delete']:
                        if not func_name.endswith(
                            ('_get', '_post', '_put', '_delete')):
                            continue
                        else:
                            # Set the fallback http method to the extention of the function name
                            parts = func_name.split('_')
                            if parts[len(parts) - 1] in ('get', 'post', 'put',
                                                         'delete'):
                                fallback_http_methods = [
                                    parts[len(parts) - 1].upper()
                                ]
                    else:
                        # Set the fallback http method to the function name
                        fallback_http_methods = [func_name.upper()]

                    if func_name == 'get':
                        endpoint_id = '%s' % view_class.__name__
                    elif func_name.endswith('_get'):
                        endpoint_id = '%s:%s' % (view_class.__name__, '_'.join(
                            func_name.split('_')[:-1]))
                    else:
                        endpoint_id = '%s:%s' % (view_class.__name__,
                                                 func_name)

                    # Get the method
                    func = getattr(view, func_name)
                    view_func_wrapper = self.func_wrapper(
                        plugin.plugin_id, func)

                    # If the http methods have been specified in the @subroute decorator
                    if hasattr(func, 'http_methods'):
                        fallback_http_methods = func.http_methods

                    fallback_endpoint = '/'
                    # If an endpoint has been specified in the @subroute decorator
                    if hasattr(func, 'endpoint'):
                        fallback_endpoint = func.endpoint

                    # Prepare fallback defaults for the page
                    if hasattr(func, 'defaults'):
                        fallback_defaults = func.defaults
                    elif func.__defaults__ is not None:
                        args, varargs, keywords, defaults = inspect.getargspec(
                            func)
                        fallback_defaults = dict(
                            zip(args[-len(defaults):], defaults))
                    else:
                        fallback_defaults = {}

                    func_routes = list()
                    if not hasattr(func, 'routes'):
                        func_routes.append({
                            'endpoint': fallback_endpoint,
                            'http_methods': fallback_http_methods,
                            'defaults': fallback_defaults
                        })
                    else:
                        func_routes = func.routes

                    # Add a route for the get function with no parameters
                    if func_name == 'get':
                        plugin._blueprint.add_url_rule(
                            view.endpoint + fallback_endpoint,
                            endpoint=endpoint_id,
                            methods=fallback_http_methods,
                            view_func=view_func_wrapper,
                            defaults=fallback_defaults)

                    for route in func_routes:
                        if 'endpoint' not in route:
                            route['endpoint'] = fallback_endpoint
                        if 'http_methods' not in route:
                            route['http_methods'] = fallback_http_methods
                        if 'defaults' not in route:
                            route['defaults'] = fallback_defaults.copy()

                        # Defaults are odd. They cannot be attached to routes with the key in the url
                        # For example: if <id> in in the url rule, it cann't be in defaults.
                        pattern = re.compile(r'<(?:.+?(?=:):)?(.+?)>')
                        if '<' in route['endpoint'] and len(
                                route['defaults']) > 0:
                            for id in re.findall(pattern, route['endpoint']):
                                try:
                                    del route['defaults'][id]
                                except:
                                    pass

                        if prism.settings.is_dev():
                            logging.info(
                                'Registered page /%s: %s %s' %
                                (blueprint_name + view.endpoint +
                                 route['endpoint'], blueprint_name + '.' +
                                 endpoint_id, route['http_methods']))

                        plugin._blueprint.add_url_rule(
                            view.endpoint + route['endpoint'],
                            endpoint=endpoint_id,
                            methods=route['http_methods'],
                            view_func=view_func_wrapper,
                            defaults=route['defaults'])

        flask_app().register_blueprint(plugin._blueprint,
                                       url_prefix='/' +
                                       blueprint_name.replace('.', '/'))

        plugin.post_init(PRISM_STATE)

        logging.down()
Example #6
0
    def _load_plugins(self):
        """ Attempts to load every enabled plugin """
        plugins_loaded = list()

        core_plugins = list()
        plugins_additional = list()

        for plugin_id, plugin_info in self.available_plugins.items():
            if plugin_info['_is_core']:
                core_plugins.append(plugin_info)
            elif plugin_info['_is_satisfied']:
                plugins_additional.append(plugin_info)

        # These will always be initialized.
        logging.info('Loading %s core plugin(s)' % len(core_plugins))
        for plugin_info in core_plugins:
            plugin = self._import_plugin(plugin_info)
            if not plugin:
                logging.error(
                    'Error: Failed to load core plugin. Offender: %s' %
                    plugin_info['id'])
                continue
            else:
                logging.good('Loaded %s' % plugin_info['id'])

            plugins_loaded.append(plugin)
        logging.down()

        logging.info('Sorting dependencies')
        sorted_plugins = []
        while plugins_additional:
            added_any = False
            for plugin in plugins_additional:
                ready_add = True
                if 'dependencies' in plugin and 'plugin' in plugin[
                        'dependencies']:
                    for dependency in plugin['dependencies']['plugin']:
                        found = False
                        for ready_plugin in sorted_plugins:
                            if ready_plugin['id'] == dependency:
                                found = True
                                break
                        if not found:
                            ready_add = False
                if ready_add:
                    added_any = True
                    sorted_plugins.append(plugin)
                    plugins_additional.remove(plugin)
            if not added_any:
                break
        plugins_additional = sorted_plugins

        logging.up('Loading %s additional plugin(s)' % len(plugins_additional))
        # Start plugins if they're set to be enabled.
        for plugin_info in plugins_additional:
            if not self.is_enabled(plugin_info['id']):
                self._insert_dummy_plugin(plugin_info)
                continue

            plugin = self._import_plugin(plugin_info)
            if not plugin:
                logging.error(
                    'Error: Failed to load additional plugin. Offender: %s' %
                    plugin_id)
                continue
            else:
                logging.good('Loaded %s' % plugin_info['id'])

            plugins_loaded.append(plugin)
        logging.down()

        logging.up('Initializing %s plugin(s)' % len(plugins_loaded))
        for plugin in plugins_loaded:
            plugin._info['_is_enabled'] = True
            self._init_plugin(plugin)
        logging.down()