Exemplo n.º 1
0
    def enable_plugin_by_db_table_id(self, plugin_table_ids):
        self._log("Enable plugins '{}'".format(plugin_table_ids), level='debug')

        # Refresh session
        s = Session()
        s.register_unmanic(s.get_installation_uuid())

        # Update enabled plugins
        if not self.ensure_session_level_for_plugins(s.level):
            return False

        # Enable the matching entries in the table
        Plugins.update(enabled=True).where(Plugins.id.in_(plugin_table_ids)).execute()

        # Fetch records
        records_by_id = self.get_plugin_list_filtered_and_sorted(id_list=plugin_table_ids)

        # Ensure they are now enabled
        for record in records_by_id:
            if record.get('enabled'):
                continue
            self._log("Failed to enable plugin '{}'".format(record.get('plugin_id')), level='debug')
            return False

        return True
Exemplo n.º 2
0
    def write_plugin_data_to_db(plugin, plugin_directory):
        # Add installed plugin to database
        plugin_data = {
            Plugins.plugin_id:        plugin.get("id"),
            Plugins.name:             plugin.get("name"),
            Plugins.author:           plugin.get("author"),
            Plugins.version:          plugin.get("version"),
            Plugins.tags:             plugin.get("tags"),
            Plugins.description:      plugin.get("description"),
            Plugins.icon:             plugin.get("icon"),
            Plugins.local_path:       plugin_directory,
            Plugins.update_available: False,
        }
        plugin_entry = Plugins.get_or_none(plugin_id=plugin.get("id"))
        if plugin_entry is not None:
            # Update the existing entry
            update_query = (Plugins
                            .update(plugin_data)
                            .where(Plugins.plugin_id == plugin.get("id")))
            update_query.execute()
        else:
            # Insert a new entry
            # Plugins are disable when first installed. This will help to prevent issues with broken plugins
            plugin_data[Plugins.enabled] = False
            Plugins.insert(plugin_data).execute()

        return True
Exemplo n.º 3
0
    def ensure_session_level_for_plugins(self, level):
        if level > 1:
            # Session level is valid for running plugins
            return True

        if level == 0:
            self._log("Plugin support not available. To enable plugin support, sign in...", level='warning')
        elif level == 1:
            self._log("Plugin support not available. Consider becoming a supporter if you wish to enable plugin support.",
                      level='warning')

        # Disable plugins
        Plugins.update(enabled=False).execute()
        return False
Exemplo n.º 4
0
    def uninstall_plugins_by_db_table_id(self, plugin_table_ids: list):
        """
        Remove a Plugin by it's DB table ID column.
        This will also remove the Plugin directory and all it's contents.

        :param plugin_table_ids:
        :return:
        """
        self._log("Uninstall plugins '{}'".format(plugin_table_ids), level='debug')

        # Fetch records
        records_by_id = self.get_plugin_list_filtered_and_sorted(id_list=plugin_table_ids)

        # Remove each plugin from disk
        for record in records_by_id:
            plugin_directory = self.get_plugin_path(record.get('plugin_id'))
            self._log("Removing plugin files from disk '{}'".format(plugin_directory), level='debug')
            try:
                shutil.rmtree(plugin_directory)
            except Exception as e:
                self._log("Exception while removing directory {}:".format(plugin_directory), message2=str(e),
                          level="exception")

        # Delete by ID in DB
        if not Plugins.delete().where(Plugins.id.in_(plugin_table_ids)).execute():
            return False

        return True
Exemplo n.º 5
0
    def set_plugin_flow(self, plugin_type, flow):
        # Delete all current flow data for this plugin type
        delete_query = PluginFlow.delete().where(PluginFlow.plugin_type == plugin_type)
        delete_query.execute()

        success = True
        priority = 1
        for plugin in flow:
            plugin_id = plugin.get('plugin_id')

            # Fetch the plugin info
            plugin_info = Plugins.select().where(Plugins.plugin_id == plugin_id).first()
            if not plugin_info:
                continue

            # Save the plugin flow
            flow_dict = {
                'plugin_id':   plugin_info.id,
                'plugin_name': plugin_info.plugin_id,
                'plugin_type': plugin_type,
                'position':    priority,
            }
            plugin_flow = PluginFlow.create(**flow_dict)
            priority += 1

            if not plugin_flow:
                success = False

        return success
Exemplo n.º 6
0
    def disable_plugin_by_db_table_id(self, plugin_table_ids):
        self._log("Disable plugins '{}'".format(plugin_table_ids), level='debug')
        # Disable the matching entries in the table
        Plugins.update(enabled=False).where(Plugins.id.in_(plugin_table_ids)).execute()

        # Fetch records
        records_by_id = self.get_plugin_list_filtered_and_sorted(id_list=plugin_table_ids)

        # Ensure they are now disabled
        for record in records_by_id:
            if not record.get('enabled'):
                continue
            self._log("Failed to disable plugin '{}'".format(record.get('plugin_id')), level='debug')
            return False

        return True
Exemplo n.º 7
0
    def flag_plugin_for_update_by_id(self, plugin_id):
        self._log("Flagging update available for installed plugin '{}'".format(plugin_id), level='debug')
        # Disable the matching entries in the table
        Plugins.update(update_available=True).where(Plugins.plugin_id == plugin_id).execute()

        # Fetch records
        records = self.get_plugin_list_filtered_and_sorted(plugin_id=plugin_id)

        # Ensure they are now disabled
        for record in records:
            if record.get('update_available'):
                continue
            self._log("Failed to flag plugin for update '{}'".format(record.get('plugin_id')), level='debug')
            return False

        return True
Exemplo n.º 8
0
    def set_enabled_plugins(self, plugin_list: list):
        """
        Update the list of enabled plugins

        :param plugin_list:
        :return:
        """
        # Remove all enabled plugins
        self.__remove_enabled_plugins()

        # Add new repos
        data = []
        plugin_ids = []
        for plugin_info in plugin_list:
            plugin = Plugins.get(plugin_id=plugin_info.get('plugin_id'))
            plugin_ids.append(plugin.id)
            if plugin:
                data.append({
                    "library_id": self.model.id,
                    "plugin_id": plugin,
                    "plugin_name": plugin.name,
                })

        # Delete all plugin flows for plugins not to be enabled for this library
        self.__trim_plugin_flow(plugin_ids)

        # Insert plugins
        EnabledPlugins.insert_many(data).execute()

        # Add default flow for newly added plugins
        self.__set_default_plugin_flow_priority(plugin_list)
Exemplo n.º 9
0
    def set_plugin_flow(self, plugin_type, library_id, flow):
        """
        Update the plugin flow for all plugins in a given plugin type

        :param plugin_type:
        :param library_id:
        :param flow:
        :return:
        """
        # Delete all current flow data for this plugin type
        delete_query = LibraryPluginFlow.delete().where(
            (LibraryPluginFlow.plugin_type == plugin_type)
            & (LibraryPluginFlow.library_id == library_id))
        delete_query.execute()

        success = True
        priority = 1
        for plugin in flow:
            plugin_id = plugin.get('plugin_id')

            # Fetch the plugin info
            plugin_info = Plugins.select().where(
                Plugins.plugin_id == plugin_id).first()
            if not plugin_info:
                continue

            # Save the plugin flow
            plugin_flow = self.set_plugin_flow_position_for_single_plugin(
                plugin_info, plugin_type, library_id, priority)
            priority += 1

            if not plugin_flow:
                success = False

        return success
Exemplo n.º 10
0
    def uninstall_plugins_by_db_table_id(self, plugin_table_ids: list):
        """
        Remove a Plugin by it's DB table ID column.
        This will also remove the Plugin directory and all it's contents.

        :param plugin_table_ids:
        :return:
        """
        self._log("Uninstall plugins '{}'".format(plugin_table_ids),
                  level='debug')

        # Fetch records
        records_by_id = self.get_plugin_list_filtered_and_sorted(
            id_list=plugin_table_ids)

        # Remove each plugin from disk
        for record in records_by_id:
            # Unload plugin modules
            try:
                PluginExecutor.unload_plugin_module(record.get('plugin_id'))
            except Exception as e:
                self._log("Exception while unloading python module {}:".format(
                    record.get('plugin_id')),
                          message2=str(e),
                          level="exception")

            # Remove from disk
            plugin_directory = self.get_plugin_path(record.get('plugin_id'))
            self._log("Removing plugin files from disk '{}'".format(
                plugin_directory),
                      level='debug')
            try:
                # Delete the info file first to prevent any other process trying to read the plugin.
                # Without the info file, the plugin is effectivly uninstalled
                info_file = os.path.join(plugin_directory, 'info.json')
                if os.path.exists(info_file):
                    os.remove(info_file)
                # Cleanup the rest of the plugin directory
                shutil.rmtree(plugin_directory)
            except Exception as e:
                self._log("Exception while removing directory {}:".format(
                    plugin_directory),
                          message2=str(e),
                          level="exception")

        # Unlink from library by ID in DB
        EnabledPlugins.delete().where(
            EnabledPlugins.plugin_id.in_(plugin_table_ids)).execute()

        # Delete by ID in DB
        if not Plugins.delete().where(
                Plugins.id.in_(plugin_table_ids)).execute():
            return False

        return True
Exemplo n.º 11
0
    def get_plugin_list_filtered_and_sorted(self, order=None, start=0, length=None, search_value=None, id_list=None,
                                            enabled=None, plugin_id=None, plugin_type=None):
        try:
            query = (Plugins.select())

            if plugin_type:
                join_condition = (
                    (PluginFlow.plugin_id == Plugins.id) &
                    (PluginFlow.plugin_type == plugin_type))
                query = query.join(PluginFlow, join_type='LEFT OUTER JOIN', on=join_condition)

            if id_list:
                query = query.where(Plugins.id.in_(id_list))

            if search_value:
                query = query.where(
                    (Plugins.name.contains(search_value)) |
                    (Plugins.author.contains(search_value)) |
                    (Plugins.tags.contains(search_value))
                )

            if plugin_id is not None:
                query = query.where(Plugins.plugin_id.in_([plugin_id]))

            if enabled is not None:
                query = query.where(Plugins.enabled == enabled)

            # Get order by
            if order:
                for o in order:
                    if o.get("model"):
                        model = o.get("model")
                    else:
                        model = Plugins
                    if o.get("dir") == "asc":
                        order_by = attrgetter(o.get("column"))(model).asc()
                    else:
                        order_by = attrgetter(o.get("column"))(model).desc()

                    query = query.order_by_extend(order_by)

            if length:
                query = query.limit(length).offset(start)

            return query.dicts()

        except Plugins.DoesNotExist:
            # No plugin entries exist yet
            self._log("No plugins exist yet.", level="warning")
Exemplo n.º 12
0
    def write_plugin_data_to_db(plugin, plugin_directory):
        # Add installed plugin to database
        plugin_data = {
            Plugins.plugin_id: plugin.get("plugin_id"),
            Plugins.name: plugin.get("name"),
            Plugins.author: plugin.get("author"),
            Plugins.version: plugin.get("version"),
            Plugins.tags: plugin.get("tags"),
            Plugins.description: plugin.get("description"),
            Plugins.icon: plugin.get("icon"),
            Plugins.local_path: plugin_directory,
            Plugins.update_available: False,
        }
        plugin_entry = Plugins.get_or_none(plugin_id=plugin.get("plugin_id"))
        if plugin_entry is not None:
            # Update the existing entry
            update_query = (Plugins.update(plugin_data).where(
                Plugins.plugin_id == plugin.get("plugin_id")))
            update_query.execute()
        else:
            # Insert a new entry
            Plugins.insert(plugin_data).execute()

        return True
Exemplo n.º 13
0
    def get_plugin_list_filtered_and_sorted(self,
                                            order=None,
                                            start=0,
                                            length=None,
                                            search_value=None,
                                            id_list=None,
                                            enabled=None,
                                            plugin_id=None):
        try:
            query = (Plugins.select())

            if id_list:
                query = query.where(Plugins.id.in_(id_list))

            if search_value:
                query = query.where((Plugins.name.contains(search_value))
                                    | (Plugins.author.contains(search_value))
                                    | (Plugins.tags.contains(search_value)))

            if plugin_id is not None:
                query = query.where(Plugins.plugin_id.in_([plugin_id]))

            if enabled is not None:
                query = query.where(Plugins.enabled == enabled)

            # Get order by
            order_by = None
            if order:
                if order.get("dir") == "asc":
                    order_by = attrgetter(order.get("column"))(Plugins).asc()
                else:
                    order_by = attrgetter(order.get("column"))(Plugins).desc()

            if order_by and length:
                query = query.order_by(order_by).limit(length).offset(start)

            return query.dicts()

        except Plugins.DoesNotExist:
            # No plugin entries exist yet
            self._log("No plugins exist yet.", level="warning")
Exemplo n.º 14
0
    def __set_default_plugin_flow_priority(self, plugin_list):
        from unmanic.libs.unplugins import PluginExecutor
        plugin_executor = PluginExecutor()
        from unmanic.libs.plugins import PluginsHandler
        plugin_handler = PluginsHandler()

        # Fetch current items
        configured_plugin_ids = []
        query = LibraryPluginFlow.select().where(
            LibraryPluginFlow.library_id == self.model.id)
        for flow_item in query:
            configured_plugin_ids.append(flow_item.plugin_id.plugin_id)

        for plugin in plugin_list:
            # Ignore already configured plugins
            if plugin.get('plugin_id') in configured_plugin_ids:
                continue
            plugin_info = plugin_handler.get_plugin_info(
                plugin.get('plugin_id'))
            plugin_priorities = plugin_info.get('priorities')
            if plugin_priorities:
                # Fetch the plugin info back from the DB
                plugin_info = Plugins.select().where(
                    Plugins.plugin_id == plugin.get("plugin_id")).first()
                # Fetch all plugin types in this plugin
                plugin_types_in_plugin = plugin_executor.get_all_plugin_types_in_plugin(
                    plugin.get("plugin_id"))
                # Loop over the plugin types in this plugin
                for plugin_type in plugin_types_in_plugin:
                    # get the plugin runner function name for this runner
                    plugin_type_meta = plugin_executor.get_plugin_type_meta(
                        plugin_type)
                    runner_string = plugin_type_meta.plugin_runner()
                    if plugin_priorities.get(runner_string) and int(
                            plugin_priorities.get(runner_string, 0)) > 0:
                        # If the runner has a priority set and that value is greater than 0 (default that wont set anything),
                        # Save the priority
                        PluginsHandler.set_plugin_flow_position_for_single_plugin(
                            plugin_info, plugin_type, self.model.id,
                            plugin_priorities.get(runner_string))
Exemplo n.º 15
0
    def uninstall_plugins_by_db_table_id(self, plugin_table_ids):
        self._log("Uninstall plugins '{}'".format(plugin_table_ids),
                  level='debug')

        # Fetch records
        records_by_id = self.get_plugin_list_filtered_and_sorted(
            id_list=plugin_table_ids)

        # Remove each plugin from disk
        for record in records_by_id:
            plugin_directory = self.get_plugin_path(record.get('plugin_id'))
            self._log("Removing plugin files from disk '{}'".format(
                plugin_directory),
                      level='debug')
            shutil.rmtree(plugin_directory)

        # Delete by ID in DB
        with db.atomic():
            if not Plugins.delete().where(
                    Plugins.id.in_(plugin_table_ids)).execute():
                return False

        return True
Exemplo n.º 16
0
 def get_total_plugin_list_count(self):
     task_query = Plugins.select().order_by(Plugins.id.desc())
     return task_query.count()
Exemplo n.º 17
0
    def get_plugin_list_filtered_and_sorted(self,
                                            order=None,
                                            start=0,
                                            length=None,
                                            search_value=None,
                                            id_list=None,
                                            enabled=None,
                                            plugin_id=None,
                                            plugin_type=None,
                                            library_id=None):
        try:
            query = (Plugins.select())

            if plugin_type:
                if library_id is not None:
                    join_condition = (
                        (LibraryPluginFlow.plugin_id == Plugins.id) &
                        (LibraryPluginFlow.plugin_type == plugin_type) &
                        (LibraryPluginFlow.library_id == library_id))
                else:
                    join_condition = (
                        (LibraryPluginFlow.plugin_id == Plugins.id) &
                        (LibraryPluginFlow.plugin_type == plugin_type))
                query = query.join(LibraryPluginFlow,
                                   join_type='LEFT OUTER JOIN',
                                   on=join_condition)

            if id_list:
                query = query.where(Plugins.id.in_(id_list))

            if search_value:
                query = query.where((Plugins.name.contains(search_value))
                                    | (Plugins.author.contains(search_value))
                                    | (Plugins.tags.contains(search_value)))

            if plugin_id is not None:
                query = query.where(Plugins.plugin_id.in_([plugin_id]))

            # Deprecate this "enabled" status as plugins are now enabled when the are assigned to a library
            if enabled is not None:
                raise Exception(
                    "Fetching plugins by 'enabled' status is deprecated")

            if library_id is not None:
                join_condition = ((EnabledPlugins.plugin_id == Plugins.id) &
                                  (EnabledPlugins.library_id == library_id))
                query = query.join(EnabledPlugins,
                                   join_type='LEFT OUTER JOIN',
                                   on=join_condition)
                query = query.where(EnabledPlugins.plugin_id != None)

            # Get order by
            if order:
                for o in order:
                    if o.get("model"):
                        model = o.get("model")
                    else:
                        model = Plugins
                    if o.get("dir") == "asc":
                        order_by = attrgetter(o.get("column"))(model).asc()
                    else:
                        order_by = attrgetter(o.get("column"))(model).desc()

                    query = query.order_by_extend(order_by)

            if length:
                query = query.limit(length).offset(start)

            return query.dicts()

        except Plugins.DoesNotExist:
            # No plugin entries exist yet
            self._log("No plugins exist yet.", level="warning")