This file is indexed.

/usr/share/pyshared/yapsy/ConfigurablePluginManager.py is in python-yapsy 1.10.2-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
#!/usr/bin/python
# -*- coding: utf-8; tab-width: 4; indent-tabs-mode: t; python-indent: 4 -*-

"""
Role
====

Defines plugin managers that can handle configuration files similar to
the ini files manipulated by Python's ConfigParser module.

API
===
"""

from yapsy.IPlugin import IPlugin


from yapsy.PluginManagerDecorator import PluginManagerDecorator
from yapsy.PluginManager import PLUGIN_NAME_FORBIDEN_STRING



class ConfigurablePluginManager(PluginManagerDecorator):
	"""
	A plugin manager that also manages a configuration file.

	The configuration file will be accessed through a ``ConfigParser``
	derivated object. The file can be used for other purpose by the
	application using this plugin manager as it will only add a new
	specific section ``[Plugin Management]`` for itself and also new
	sections for some plugins that will start with ``[Plugin:...]``
	(only the plugins that explicitly requires to save configuration
	options will have this kind of section).

	.. warning:: when giving/building the list of plugins to activate
	             by default, there must not be any space in the list
	             (neither in the names nor in between)
	"""
	
	CONFIG_SECTION_NAME = "Plugin Management"


	def __init__(self,
				 configparser_instance=None,
				 config_change_trigger= lambda x:True,
				 decorated_manager=None,
				 # The following args will only be used if we need to
				 # create a default PluginManager
				 categories_filter={"Default":IPlugin}, 
				 directories_list=None, 
				 plugin_info_ext="yapsy-plugin"):
		"""
		Create the plugin manager and record the ConfigParser instance
		that will be used afterwards.
		
		The ``config_change_trigger`` argument can be used to set a
		specific method to call when the configuration is
		altered. This will let the client application manage the way
		they want the configuration to be updated (e.g. write on file
		at each change or at precise time intervalls or whatever....)
		"""
		# Create the base decorator class
		PluginManagerDecorator.__init__(self,decorated_manager,
										categories_filter,
										directories_list,
										plugin_info_ext)
		self.setConfigParser(configparser_instance, config_change_trigger)


	def setConfigParser(self,configparser_instance,config_change_trigger):
		"""
		Set the ConfigParser instance.
		"""
		self.config_parser = configparser_instance
		# set the (optional) fucntion to be called when the
		# configuration is changed:
		self.config_has_changed = config_change_trigger
		
	def __getCategoryPluginsListFromConfig(self, plugin_list_str):
		"""
		Parse the string describing the list of plugins to activate,
		to discover their actual names and return them.
		"""
		return plugin_list_str.strip(" ").split("%s"%PLUGIN_NAME_FORBIDEN_STRING)

	def __getCategoryPluginsConfigFromList(self, plugin_list):
		"""
		Compose a string describing the list of plugins to activate
		"""
		return PLUGIN_NAME_FORBIDEN_STRING.join(plugin_list)
		
	def __getCategoryOptionsName(self,category_name):
		"""
		Return the appropirately formated version of the category's
		option.
		"""
		return "%s_plugins_to_load" % category_name.replace(" ","_")

	def __addPluginToConfig(self,category_name, plugin_name):
		"""
		Utility function to add a plugin to the list of plugin to be
		activated.
		"""
		# check that the section is here
		if not self.config_parser.has_section(self.CONFIG_SECTION_NAME):
			self.config_parser.add_section(self.CONFIG_SECTION_NAME)
		# check that the category's list of activated plugins is here too
		option_name = self.__getCategoryOptionsName(category_name)
		if not self.config_parser.has_option(self.CONFIG_SECTION_NAME, option_name):
			# if there is no list yet add a new one
			self.config_parser.set(self.CONFIG_SECTION_NAME,option_name,plugin_name)
			return self.config_has_changed()
		else:
			# get the already existing list and append the new
			# activated plugin to it.
			past_list_str = self.config_parser.get(self.CONFIG_SECTION_NAME,option_name)
			past_list = self.__getCategoryPluginsListFromConfig(past_list_str)
			# make sure we don't add it twice
			if plugin_name not in past_list: 
				past_list.append(plugin_name)
				new_list_str = self.__getCategoryPluginsConfigFromList(past_list)
				self.config_parser.set(self.CONFIG_SECTION_NAME,option_name,new_list_str)
				return self.config_has_changed()

	def __removePluginFromConfig(self,category_name, plugin_name):
		"""
		Utility function to add a plugin to the list of plugin to be
		activated.
		"""
		# check that the section is here
		if not self.config_parser.has_section(self.CONFIG_SECTION_NAME):
			# then nothing to remove :)
			return 
		# check that the category's list of activated plugins is here too
		option_name = self.__getCategoryOptionsName(category_name)
		if not self.config_parser.has_option(self.CONFIG_SECTION_NAME, option_name):
			# if there is no list still nothing to do
			return
		else:
			# get the already existing list
			past_list_str = self.config_parser.get(self.CONFIG_SECTION_NAME,option_name)
			past_list = self.__getCategoryPluginsListFromConfig(past_list_str)
			if plugin_name in past_list:
				past_list.remove(plugin_name)
				new_list_str = self.__getCategoryPluginsConfigFromList(past_list)
				self.config_parser.set(self.CONFIG_SECTION_NAME,option_name,new_list_str)
				self.config_has_changed()		
			


	def registerOptionFromPlugin(self, 
								 category_name, plugin_name, 
								 option_name, option_value):
		"""
		To be called from a plugin object, register a given option in
		the name of a given plugin.
		"""
		section_name = "%s Plugin: %s" % (category_name,plugin_name)
		# if the plugin's section is not here yet, create it
		if not self.config_parser.has_section(section_name):
			self.config_parser.add_section(section_name)
		# set the required option
		self.config_parser.set(section_name,option_name,option_value)
		self.config_has_changed()

	def hasOptionFromPlugin(self, 
							category_name, plugin_name, option_name):
		"""
		To be called from a plugin object, return True if the option
		has already been registered.
		"""
		section_name = "%s Plugin: %s" % (category_name,plugin_name)
		return self.config_parser.has_section(section_name) and self.config_parser.has_option(section_name,option_name)

	def readOptionFromPlugin(self, 
							 category_name, plugin_name, option_name):
		"""
		To be called from a plugin object, read a given option in
		the name of a given plugin.
		"""
		section_name = "%s Plugin: %s" % (category_name,plugin_name)
		return self.config_parser.get(section_name,option_name)


	def __decoratePluginObject(self, category_name, plugin_name, plugin_object):
		"""
		Add two methods to the plugin objects that will make it
		possible for it to benefit from this class's api concerning
		the management of the options.
		"""
		plugin_object.setConfigOption = lambda x,y: self.registerOptionFromPlugin(category_name,
																				  plugin_name,
																				  x,y)
		plugin_object.setConfigOption.__doc__ = self.registerOptionFromPlugin.__doc__
		plugin_object.getConfigOption = lambda x: self.readOptionFromPlugin(category_name,
																			plugin_name,
																			x)
		plugin_object.getConfigOption.__doc__ = self.readOptionFromPlugin.__doc__
		plugin_object.hasConfigOption = lambda x: self.hasOptionFromPlugin(category_name,
																		   plugin_name,
																		   x)
		plugin_object.hasConfigOption.__doc__ = self.hasOptionFromPlugin.__doc__

	def activatePluginByName(self, plugin_name, category_name="Default", save_state=True):
		"""
		Activate a plugin, , and remember it (in the config file).

		If you want the plugin to benefit from the configuration
		utility defined by this manager, it is crucial to use this
		method to activate a plugin and not call the plugin object's
		``activate`` method. In fact, this method will also "decorate"
		the plugin object so that it can use this class's methods to
		register its own options.
		
		By default, the plugin's activation is registered in the
		config file but if you d'ont want this set the 'save_state'
		argument to False.
		"""
		# first decorate the plugin
		pta = self._component.getPluginByName(plugin_name,category_name)
		if pta is None:
			return None
		self.__decoratePluginObject(category_name,plugin_name,pta.plugin_object)		
		# activate the plugin
		plugin_object = self._component.activatePluginByName(plugin_name,category_name)
		# check the activation and then optionally set the config option
		if plugin_object.is_activated:
			if save_state:
				self.__addPluginToConfig(category_name,plugin_name)
			return plugin_object
		return None

	def deactivatePluginByName(self, plugin_name, category_name="Default", save_state=True):
		"""
		Deactivate a plugin, and remember it (in the config file).

		By default, the plugin's deactivation is registered in the
		config file but if you d'ont want this set the ``save_state``
		argument to False.
		"""
		# activate the plugin
		plugin_object = self._component.deactivatePluginByName(plugin_name,category_name)
		if plugin_object is None:
			return None
		# check the deactivation and then optionnally set the config option
		if not plugin_object.is_activated:
			if save_state:
				self.__removePluginFromConfig(category_name,plugin_name)
				return plugin_object
		return None

	def loadPlugins(self,callback=None):
		"""
		Walk through the plugins' places and look for plugins.  Then
		for each plugin candidate look for its category, load it and
		stores it in the appropriate slot of the ``category_mapping``.
		"""
 		self._component.loadPlugins()
		# now load the plugins according to the recorded configuration
		if self.config_parser.has_section(self.CONFIG_SECTION_NAME):
			# browse all the categories
			for category_name in self._component.category_mapping.keys():
				# get the list of plugins to be activated for this
				# category
				option_name = "%s_plugins_to_load"%category_name
				if self.config_parser.has_option(self.CONFIG_SECTION_NAME,
												 option_name):
					plugin_list_str = self.config_parser.get(self.CONFIG_SECTION_NAME,
															 option_name)
					plugin_list = self.__getCategoryPluginsListFromConfig(plugin_list_str)
					# activate all the plugins that should be
					# activated
					for plugin_name in plugin_list:
						self.activatePluginByName(plugin_name,category_name)