PluginVulture.py

changeset 1
ea6aed49cd69
parent 0
9b743f8d436b
child 2
b517a1c5d5de
equal deleted inserted replaced
0:9b743f8d436b 1:ea6aed49cd69
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2015 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the radon code metrics plug-in.
8 """
9
10 from __future__ import unicode_literals
11
12 import os
13
14 from PyQt5.QtCore import pyqtSignal, QObject, QTranslator
15
16 from E5Gui.E5Application import e5App
17 from E5Gui.E5Action import E5Action
18
19 import Preferences
20
21 # Start-Of-Header
22 name = "PluginVulture"
23 author = "Detlev Offenbach <detlev@die-offenbachs.de>"
24 autoactivate = True
25 deactivateable = True
26 version = "0.1.0"
27 className = "VulturePlugin"
28 packageName = "VultureChecker"
29 shortDescription = "Plug-in to detect unused code using the vulture library"
30 longDescription = (
31 """Plug-in to detect unused code using the vulture library."""
32 )
33 needsRestart = False
34 pyqtApi = 2
35 python2Compatible = True
36 # End-Of-Header
37
38 error = ""
39
40
41 class VulturePlugin(QObject):
42 """
43 Class documentation goes here.
44
45 @signal metricsDone(str, dict) emitted when the code metrics were
46 determined for a file
47 @signal error(str, str) emitted in case of an error
48 @signal batchFinished() emitted when a style check batch is done
49 """
50 batchFinished = pyqtSignal()
51
52 def __init__(self, ui):
53 """
54 Constructor
55
56 @param ui reference to the user interface object (UI.UserInterface)
57 """
58 super(VulturePlugin, self).__init__(ui)
59 self.__ui = ui
60 self.__initialize()
61
62 self.backgroundService = e5App().getObject("BackgroundService")
63
64 path = os.path.join(os.path.dirname(__file__), packageName)
65 try:
66 self.backgroundService.serviceConnect(
67 'vulture', 'Python2', path, 'VultureCheckerService',
68 self.vultureCheckDone,
69 onErrorCallback=self.serviceErrorPy2,
70 onBatchDone=self.batchJobDone)
71 self.backgroundService.serviceConnect(
72 'vulture', 'Python3', path, 'VultureCheckerService',
73 self.vultureCheckDone,
74 onErrorCallback=self.serviceErrorPy3,
75 onBatchDone=self.batchJobDone)
76 except TypeError:
77 # backward compatibility for eric 6.0
78 self.backgroundService.serviceConnect(
79 'vulture', 'Python2', path, 'VultureCheckerService',
80 self.vultureCheckDone,
81 onErrorCallback=self.serviceErrorPy2)
82 self.backgroundService.serviceConnect(
83 'vulture', 'Python3', path, 'VultureCheckerService',
84 self.vultureCheckDone,
85 onErrorCallback=self.serviceErrorPy3)
86
87 self.queuedBatches = []
88 self.batchesFinished = True
89
90 self.__translator = None
91 self.__loadTranslator()
92
93 def __serviceError(self, fn, msg):
94 """
95 Private slot handling service errors.
96
97 @param fn file name
98 @type str
99 @param msg message text
100 @type str
101 """
102 self.error.emit(fn, msg)
103
104 def serviceErrorPy2(self, fx, lang, fn, msg):
105 """
106 Public slot handling service errors for Python 2.
107
108 @param fx service name
109 @type str
110 @param lang language
111 @type str
112 @param fn file name
113 @type str
114 @param msg message text
115 @type str
116 """
117 if fx in ['vulture', 'batch_vulture'] and \
118 lang == 'Python2':
119 if fx == 'vulture':
120 self.__serviceError(fn, msg)
121 else:
122 self.__serviceError(self.tr("Python 2 batch job"), msg)
123 self.batchJobDone(fx, lang)
124
125 def serviceErrorPy3(self, fx, lang, fn, msg):
126 """
127 Public slot handling service errors for Python 3.
128
129 @param fx service name
130 @type str
131 @param lang language
132 @type str
133 @param fn file name
134 @type str
135 @param msg message text
136 @type str
137 """
138 if fx in ['vulture', 'batch_vulture'] and \
139 lang == 'Python3':
140 if fx == 'vulture':
141 self.__serviceError(fn, msg)
142 else:
143 self.__serviceError(self.tr("Python 3 batch job"), msg)
144 self.batchJobDone(fx, lang)
145
146 def batchJobDone(self, fx, lang):
147 """
148 Public slot handling the completion of a batch job.
149
150 @param fx service name
151 @type str
152 @param lang language
153 @type str
154 """
155 if fx in ['vulture', 'batch_vulture']:
156 if lang in self.queuedBatches:
157 self.queuedBatches.remove(lang)
158 # prevent sending the signal multiple times
159 if len(self.queuedBatches) == 0 and not self.batchesFinished:
160 self.batchFinished.emit()
161 self.batchesFinished = True
162
163 def __initialize(self):
164 """
165 Private slot to (re)initialize the plug-in.
166 """
167 self.__projectAct = None
168 self.__projectVultureCheckerDialog = None
169
170 def vultureCheck(self, lang, filenames):
171 """
172 Public method to prepare a vulture check for a Python project.
173
174 @param lang language of the files or None to determine by internal
175 algorithm
176 @type str or None
177 @param filenames list of file names to include in the check
178 @type list of str
179 """
180 # TODO: implement this
181
182 def activate(self):
183 """
184 Public method to activate this plug-in.
185
186 @return tuple of None and activation status (boolean)
187 """
188 global error
189 error = "" # clear previous error
190
191 menu = e5App().getObject("Project").getMenu("Checks")
192 if menu:
193 self.__projectAct = E5Action(
194 self.tr('Check Unused Code'),
195 self.tr('&Unused Code...'), 0, 0,
196 self, 'project_check_vulture')
197 self.__projectAct.setStatusTip(
198 self.tr('Check for unused code'))
199 self.__projectAct.setWhatsThis(self.tr(
200 """<b>Check Unused Code...</b>"""
201 """<p>This checks a Python project for unused code.</p>"""
202 ))
203 self.__projectAct.triggered.connect(
204 self.__projectVultureCheck)
205 e5App().getObject("Project").addE5Actions([self.__projectAct])
206 menu.addAction(self.__projectAct)
207
208 e5App().getObject("Project").showMenu.connect(self.__projectShowMenu)
209 e5App().getObject("Project").projectClosed.connect(
210 self.__projectClosed)
211
212 return None, True
213
214 def deactivate(self):
215 """
216 Public method to deactivate this plug-in.
217 """
218 e5App().getObject("Project").showMenu.disconnect(
219 self.__projectShowMenu)
220 e5App().getObject("Project").projectClosed.disconnect(
221 self.__projectClosed)
222
223 menu = e5App().getObject("Project").getMenu("Show")
224 if menu:
225 if self.__projectAct is not None:
226 menu.removeAction(self.__projectAct)
227 e5App().getObject("Project").removeE5Actions(
228 [self.self.__projectAct])
229
230 def __loadTranslator(self):
231 """
232 Private method to load the translation file.
233 """
234 if self.__ui is not None:
235 loc = self.__ui.getLocale()
236 if loc and loc != "C":
237 locale_dir = os.path.join(
238 os.path.dirname(__file__), "VultureChecker", "i18n")
239 translation = "vulture_{0}".format(loc)
240 translator = QTranslator(None)
241 loaded = translator.load(translation, locale_dir)
242 if loaded:
243 self.__translator = translator
244 e5App().installTranslator(self.__translator)
245 else:
246 print("Warning: translation file '{0}' could not be"
247 " loaded.".format(translation))
248 print("Using default.")
249
250 def __projectShowMenu(self, menuName, menu):
251 """
252 Private slot called, when the the project menu or a submenu is
253 about to be shown.
254
255 @param menuName name of the menu to be shown
256 @type str
257 @param menu reference to the menu
258 @type QMenu
259 """
260 if menuName == "Check":
261 if self.__projectAct is not None:
262 self.__projectAct.setEnabled(
263 e5App().getObject("Project").getProjectLanguage() in
264 ["Python3", "Python2", "Python"])
265
266 def __projectVultureCheck(self):
267 """
268 Private slot used to check the project for unused code.
269 """
270 project = e5App().getObject("Project")
271 project.saveAllScripts()
272 ppath = project.getProjectPath()
273 files = [os.path.join(ppath, file)
274 for file in project.pdata["SOURCES"]
275 if file.endswith(
276 tuple(Preferences.getPython("Python3Extensions")) +
277 tuple(Preferences.getPython("PythonExtensions")))]
278
279 if self.__projectVultureCheckerDialog is None:
280 from VultureChecker.VultureCheckerDialog import \
281 VultureCheckerDialog
282 self.__projectRawMetricsDialog = VultureCheckerDialog(self)
283 self.__projectVultureCheckerDialog.show()
284 self.__projectVultureCheckerDialog.prepare(files, project)

eric ide

mercurial