File: loader.py

package info (click to toggle)
geany-plugins 1.24%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 17,532 kB
  • ctags: 10,926
  • sloc: ansic: 89,639; sh: 11,434; python: 1,365; makefile: 1,302
file content (172 lines) | stat: -rw-r--r-- 4,570 bytes parent folder | download | duplicates (2)
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
import os
import imp
from collections import namedtuple
import geany

PluginInfo = namedtuple('PluginInfo', 'filename, name, version, description, author, cls')


class PluginLoader(object):

	plugins = {}

	def __init__(self, plugin_dirs):

		self.plugin_dirs = plugin_dirs

		self.available_plugins = []
		for plugin in self.iter_plugin_info():
			self.available_plugins.append(plugin)

		self.restore_loaded_plugins()


	def update_loaded_plugins_file(self):
		for path in self.plugin_dirs:
			if os.path.isdir(path):
				try:
					state_file = os.path.join(path, '.loaded_plugins')
					with open(state_file, 'w') as f:
						for plugfn in self.plugins:
							f.write("%s\n" % plugfn)
				except IOError as err:
					if err.errno == 13: #perms
						pass
					else:
						raise


	def restore_loaded_plugins(self):
		loaded_plugins = []
		for path in reversed(self.plugin_dirs):
			state_file = os.path.join(path, ".loaded_plugins")
			if os.path.exists(state_file):
				for line in open(state_file):
					line = line.strip()
					if line not in loaded_plugins:
						loaded_plugins.append(line)
		for filename in loaded_plugins:
			self.load_plugin(filename)


	def load_all_plugins(self):

		for plugin_info in self.iter_plugin_info():
			if plugin_filename.endswith('test.py'): # hack for testing
				continue
			plug = self.load_plugin(plugin_info.filename)
			if plug:
				print("Loaded plugin: %s" % plugin_info.filename)
				print("  Name: %s v%s" % (plug.name, plug.version))
				print("  Desc: %s" % plug.description)
				print("  Author: %s" % plug.author)


	def unload_all_plugins(self):

		for plugin in self.plugins:
			self.unload_plugin(plugin)


	def reload_all_plugins(self):

		self.unload_all_plugins()
		self.load_all_plugins()


	def iter_plugin_info(self):

		for d in self.plugin_dirs:
			if os.path.isdir(d):
				for current_file in os.listdir(d):
					#check inside folders inside the plugins dir so we can load .py files here as plugins
					current_path=os.path.abspath(os.path.join(d, current_file))
					if os.path.isdir(current_path):
						for plugin_folder_file in os.listdir(current_path):
							if plugin_folder_file.endswith('.py'):
								#loop around results if its fails to load will never reach yield
								for p in self.load_plugin_info(current_path,plugin_folder_file):
									yield p
									
					#not a sub directory so if it ends with .py lets just attempt to load it as a plugin
					if current_file.endswith('.py'):
						#loop around results if its fails to load will never reach yield
						for p in self.load_plugin_info(d,current_file):
							yield p
								
	def load_plugin_info(self,d,f):
		filename = os.path.abspath(os.path.join(d, f))
		if filename.endswith("test.py"):
			pass
		text = open(filename).read()
		module_name = os.path.basename(filename)[:-3]
		try:
			module = imp.load_source(module_name, filename)
		except ImportError as exc:
			print "Error: failed to import settings module ({})".format(exc)
			module=None
		if module:	
			for k, v in module.__dict__.iteritems():
				if k == geany.Plugin.__name__:
					continue
				try:
					if issubclass(v, geany.Plugin):
						inf = PluginInfo(
								filename,
								getattr(v, '__plugin_name__'),
								getattr(v, '__plugin_version__', ''),
								getattr(v, '__plugin_description__', ''),
								getattr(v, '__plugin_author__', ''),
								v)
						yield inf
						
				except TypeError:
					continue


	def load_plugin(self, filename):

		for avail in self.available_plugins:
			if avail.filename == filename:
				inst = avail.cls()
				self.plugins[filename] = inst
				self.update_loaded_plugins_file()
				geany.ui_utils.set_statusbar('GeanyPy: plugin activated: %s' %
					inst.name, True)
				return inst


	def unload_plugin(self, filename):

		try:
			plugin = self.plugins[filename]
			name = plugin.name
			plugin.cleanup()
			del self.plugins[filename]
			self.update_loaded_plugins_file()
			geany.ui_utils.set_statusbar('GeanyPy: plugin deactivated: %s' %
				name, True)
		except KeyError:
			print("Unable to unload plugin '%s': it's not loaded" % filename)


	def reload_plugin(self, filename):

		if filename in self.plugins:
			self.unload_plugin(filename)
		self.load_plugin(filename)


	def plugin_has_help(self, filename):

		for plugin_info in self.iter_plugin_info():
			if plugin_info.filename == filename:
				return hasattr(plugin_info.cls, 'show_help')


	def plugin_has_configure(self, filename):

		try:
			return hasattr(self.plugins[filename], 'show_configure')
		except KeyError:
			return None