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
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
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
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
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
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
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
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)
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
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
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")
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
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")
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))
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
def get_total_plugin_list_count(self): task_query = Plugins.select().order_by(Plugins.id.desc()) return task_query.count()
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")