src/eric7/WebBrowser/VirusTotal/VirusTotalApi.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9278
36448ca469c2
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
21 21
22 class VirusTotalAPI(QObject): 22 class VirusTotalAPI(QObject):
23 """ 23 """
24 Class implementing the <a href="http://www.virustotal.com">VirusTotal</a> 24 Class implementing the <a href="http://www.virustotal.com">VirusTotal</a>
25 API. 25 API.
26 26
27 @signal checkServiceKeyFinished(bool, str) emitted after the service key 27 @signal checkServiceKeyFinished(bool, str) emitted after the service key
28 check has been performed. It gives a flag indicating validity 28 check has been performed. It gives a flag indicating validity
29 (boolean) and an error message in case of a network error (string). 29 (boolean) and an error message in case of a network error (string).
30 @signal submitUrlError(str) emitted with the error string, if the URL scan 30 @signal submitUrlError(str) emitted with the error string, if the URL scan
31 submission returned an error. 31 submission returned an error.
32 @signal urlScanReport(str) emitted with the URL of the URL scan report page 32 @signal urlScanReport(str) emitted with the URL of the URL scan report page
33 @signal fileScanReport(str) emitted with the URL of the file scan report 33 @signal fileScanReport(str) emitted with the URL of the file scan report
34 page 34 page
35 """ 35 """
36
36 checkServiceKeyFinished = pyqtSignal(bool, str) 37 checkServiceKeyFinished = pyqtSignal(bool, str)
37 submitUrlError = pyqtSignal(str) 38 submitUrlError = pyqtSignal(str)
38 urlScanReport = pyqtSignal(str) 39 urlScanReport = pyqtSignal(str)
39 fileScanReport = pyqtSignal(str) 40 fileScanReport = pyqtSignal(str)
40 41
41 TestServiceKeyScanID = ( 42 TestServiceKeyScanID = (
42 "4feed2c2e352f105f6188efd1d5a558f24aee6971bdf96d5fdb19c197d6d3fad" 43 "4feed2c2e352f105f6188efd1d5a558f24aee6971bdf96d5fdb19c197d6d3fad"
43 ) 44 )
44 45
45 ServiceResult_ItemQueued = -2 46 ServiceResult_ItemQueued = -2
46 ServiceResult_ItemNotPresent = 0 47 ServiceResult_ItemNotPresent = 0
47 ServiceResult_ItemPresent = 1 48 ServiceResult_ItemPresent = 1
48 49
49 # HTTP Status Codes 50 # HTTP Status Codes
50 ServiceCode_InvalidKey = 202 51 ServiceCode_InvalidKey = 202
51 ServiceCode_RateLimitExceeded = 204 52 ServiceCode_RateLimitExceeded = 204
52 ServiceCode_InvalidPrivilege = 403 53 ServiceCode_InvalidPrivilege = 403
53 54
54 GetFileReportPattern = "{0}://www.virustotal.com/vtapi/v2/file/report" 55 GetFileReportPattern = "{0}://www.virustotal.com/vtapi/v2/file/report"
55 ScanUrlPattern = "{0}://www.virustotal.com/vtapi/v2/url/scan" 56 ScanUrlPattern = "{0}://www.virustotal.com/vtapi/v2/url/scan"
56 GetUrlReportPattern = "{0}://www.virustotal.com/vtapi/v2/url/report" 57 GetUrlReportPattern = "{0}://www.virustotal.com/vtapi/v2/url/report"
57 GetIpAddressReportPattern = ( 58 GetIpAddressReportPattern = "{0}://www.virustotal.com/vtapi/v2/ip-address/report"
58 "{0}://www.virustotal.com/vtapi/v2/ip-address/report"
59 )
60 GetDomainReportPattern = "{0}://www.virustotal.com/vtapi/v2/domain/report" 59 GetDomainReportPattern = "{0}://www.virustotal.com/vtapi/v2/domain/report"
61 60
62 def __init__(self, parent=None): 61 def __init__(self, parent=None):
63 """ 62 """
64 Constructor 63 Constructor
65 64
66 @param parent reference to the parent object (QObject) 65 @param parent reference to the parent object (QObject)
67 """ 66 """
68 super().__init__(parent) 67 super().__init__(parent)
69 68
70 self.__replies = [] 69 self.__replies = []
71 70
72 self.__loadSettings() 71 self.__loadSettings()
73 72
74 self.__lastIP = "" 73 self.__lastIP = ""
75 self.__lastDomain = "" 74 self.__lastDomain = ""
76 self.__ipReportDlg = None 75 self.__ipReportDlg = None
77 self.__domainReportDlg = None 76 self.__domainReportDlg = None
78 77
79 def __loadSettings(self): 78 def __loadSettings(self):
80 """ 79 """
81 Private method to load the settings. 80 Private method to load the settings.
82 """ 81 """
83 protocol = ( 82 protocol = "https" if Preferences.getWebBrowser("VirusTotalSecure") else "http"
84 "https"
85 if Preferences.getWebBrowser("VirusTotalSecure") else
86 "http"
87 )
88 self.GetFileReportUrl = self.GetFileReportPattern.format(protocol) 83 self.GetFileReportUrl = self.GetFileReportPattern.format(protocol)
89 self.ScanUrlUrl = self.ScanUrlPattern.format(protocol) 84 self.ScanUrlUrl = self.ScanUrlPattern.format(protocol)
90 self.GetUrlReportUrl = self.GetUrlReportPattern.format(protocol) 85 self.GetUrlReportUrl = self.GetUrlReportPattern.format(protocol)
91 self.GetIpAddressReportUrl = self.GetIpAddressReportPattern.format( 86 self.GetIpAddressReportUrl = self.GetIpAddressReportPattern.format(protocol)
92 protocol)
93 self.GetDomainReportUrl = self.GetDomainReportPattern.format(protocol) 87 self.GetDomainReportUrl = self.GetDomainReportPattern.format(protocol)
94 88
95 self.errorMessages = { 89 self.errorMessages = {
96 204: self.tr("Request limit has been reached."), 90 204: self.tr("Request limit has been reached."),
97 0: self.tr("Requested item is not present."), 91 0: self.tr("Requested item is not present."),
98 -2: self.tr("Requested item is still queued."), 92 -2: self.tr("Requested item is still queued."),
99 } 93 }
100 94
101 def preferencesChanged(self): 95 def preferencesChanged(self):
102 """ 96 """
103 Public slot to handle a change of preferences. 97 Public slot to handle a change of preferences.
104 """ 98 """
105 self.__loadSettings() 99 self.__loadSettings()
106 100
107 def checkServiceKeyValidity(self, key, protocol=""): 101 def checkServiceKeyValidity(self, key, protocol=""):
108 """ 102 """
109 Public method to check the validity of the given service key. 103 Public method to check the validity of the given service key.
110 104
111 @param key service key (string) 105 @param key service key (string)
112 @param protocol protocol used to access VirusTotal (string) 106 @param protocol protocol used to access VirusTotal (string)
113 """ 107 """
114 urlStr = ( 108 urlStr = (
115 self.GetFileReportUrl 109 self.GetFileReportUrl
116 if protocol == "" else 110 if protocol == ""
117 self.GetFileReportPattern.format(protocol) 111 else self.GetFileReportPattern.format(protocol)
118 ) 112 )
119 request = QNetworkRequest(QUrl(urlStr)) 113 request = QNetworkRequest(QUrl(urlStr))
120 request.setHeader(QNetworkRequest.KnownHeaders.ContentTypeHeader, 114 request.setHeader(
121 "application/x-www-form-urlencoded") 115 QNetworkRequest.KnownHeaders.ContentTypeHeader,
122 params = QByteArray("apikey={0}&resource={1}".format( 116 "application/x-www-form-urlencoded",
123 key, self.TestServiceKeyScanID).encode("utf-8")) 117 )
124 118 params = QByteArray(
125 import WebBrowser.WebBrowserWindow 119 "apikey={0}&resource={1}".format(key, self.TestServiceKeyScanID).encode(
126 nam = ( 120 "utf-8"
127 WebBrowser.WebBrowserWindow.WebBrowserWindow.networkManager() 121 )
128 ) 122 )
123
124 import WebBrowser.WebBrowserWindow
125
126 nam = WebBrowser.WebBrowserWindow.WebBrowserWindow.networkManager()
129 reply = nam.post(request, params) 127 reply = nam.post(request, params)
130 reply.finished.connect( 128 reply.finished.connect(lambda: self.__checkServiceKeyValidityFinished(reply))
131 lambda: self.__checkServiceKeyValidityFinished(reply)) 129 self.__replies.append(reply)
132 self.__replies.append(reply) 130
133
134 def __checkServiceKeyValidityFinished(self, reply): 131 def __checkServiceKeyValidityFinished(self, reply):
135 """ 132 """
136 Private slot to determine the result of the service key validity check. 133 Private slot to determine the result of the service key validity check.
137 134
138 @param reply reference to the network reply 135 @param reply reference to the network reply
139 @type QNetworkReply 136 @type QNetworkReply
140 """ 137 """
141 res = False 138 res = False
142 msg = "" 139 msg = ""
143 140
144 if reply.error() == QNetworkReply.NetworkError.NoError: 141 if reply.error() == QNetworkReply.NetworkError.NoError:
145 res = True 142 res = True
146 elif reply.error() == self.ServiceCode_InvalidKey: 143 elif reply.error() == self.ServiceCode_InvalidKey:
147 res = False 144 res = False
148 else: 145 else:
149 msg = reply.errorString() 146 msg = reply.errorString()
150 self.__replies.remove(reply) 147 self.__replies.remove(reply)
151 reply.deleteLater() 148 reply.deleteLater()
152 149
153 self.checkServiceKeyFinished.emit(res, msg) 150 self.checkServiceKeyFinished.emit(res, msg)
154 151
155 def submitUrl(self, url): 152 def submitUrl(self, url):
156 """ 153 """
157 Public method to submit an URL to be scanned. 154 Public method to submit an URL to be scanned.
158 155
159 @param url url to be scanned (QUrl) 156 @param url url to be scanned (QUrl)
160 """ 157 """
161 request = QNetworkRequest(QUrl(self.ScanUrlUrl)) 158 request = QNetworkRequest(QUrl(self.ScanUrlUrl))
162 request.setHeader(QNetworkRequest.KnownHeaders.ContentTypeHeader, 159 request.setHeader(
163 "application/x-www-form-urlencoded") 160 QNetworkRequest.KnownHeaders.ContentTypeHeader,
164 params = QByteArray("apikey={0}&url=".format( 161 "application/x-www-form-urlencoded",
165 Preferences.getWebBrowser("VirusTotalServiceKey")) 162 )
166 .encode("utf-8")).append(QUrl.toPercentEncoding(url.toString())) 163 params = QByteArray(
167 164 "apikey={0}&url=".format(
168 import WebBrowser.WebBrowserWindow 165 Preferences.getWebBrowser("VirusTotalServiceKey")
169 nam = ( 166 ).encode("utf-8")
170 WebBrowser.WebBrowserWindow.WebBrowserWindow.networkManager() 167 ).append(QUrl.toPercentEncoding(url.toString()))
171 ) 168
169 import WebBrowser.WebBrowserWindow
170
171 nam = WebBrowser.WebBrowserWindow.WebBrowserWindow.networkManager()
172 reply = nam.post(request, params) 172 reply = nam.post(request, params)
173 reply.finished.connect(lambda: self.__submitUrlFinished(reply)) 173 reply.finished.connect(lambda: self.__submitUrlFinished(reply))
174 self.__replies.append(reply) 174 self.__replies.append(reply)
175 175
176 def __submitUrlFinished(self, reply): 176 def __submitUrlFinished(self, reply):
177 """ 177 """
178 Private slot to determine the result of the URL scan submission. 178 Private slot to determine the result of the URL scan submission.
179 179
180 @param reply reference to the network reply 180 @param reply reference to the network reply
181 @type QNetworkReply 181 @type QNetworkReply
182 """ 182 """
183 if reply.error() == QNetworkReply.NetworkError.NoError: 183 if reply.error() == QNetworkReply.NetworkError.NoError:
184 result = json.loads(str(reply.readAll(), "utf-8")) 184 result = json.loads(str(reply.readAll(), "utf-8"))
191 else: 191 else:
192 msg = result["verbose_msg"] 192 msg = result["verbose_msg"]
193 self.submitUrlError.emit(msg) 193 self.submitUrlError.emit(msg)
194 elif reply.error() == self.ServiceCode_RateLimitExceeded: 194 elif reply.error() == self.ServiceCode_RateLimitExceeded:
195 self.submitUrlError.emit( 195 self.submitUrlError.emit(
196 self.errorMessages[result[self.ServiceCode_RateLimitExceeded]]) 196 self.errorMessages[result[self.ServiceCode_RateLimitExceeded]]
197 )
197 else: 198 else:
198 self.submitUrlError.emit(reply.errorString()) 199 self.submitUrlError.emit(reply.errorString())
199 self.__replies.remove(reply) 200 self.__replies.remove(reply)
200 reply.deleteLater() 201 reply.deleteLater()
201 202
202 def __getUrlScanReportUrl(self, scanId): 203 def __getUrlScanReportUrl(self, scanId):
203 """ 204 """
204 Private method to get the report URL for a URL scan. 205 Private method to get the report URL for a URL scan.
205 206
206 @param scanId ID of the scan to get the report URL for (string) 207 @param scanId ID of the scan to get the report URL for (string)
207 """ 208 """
208 request = QNetworkRequest(QUrl(self.GetUrlReportUrl)) 209 request = QNetworkRequest(QUrl(self.GetUrlReportUrl))
209 request.setHeader(QNetworkRequest.KnownHeaders.ContentTypeHeader, 210 request.setHeader(
210 "application/x-www-form-urlencoded") 211 QNetworkRequest.KnownHeaders.ContentTypeHeader,
211 params = QByteArray("apikey={0}&resource={1}".format( 212 "application/x-www-form-urlencoded",
212 Preferences.getWebBrowser("VirusTotalServiceKey"), scanId) 213 )
213 .encode("utf-8")) 214 params = QByteArray(
214 215 "apikey={0}&resource={1}".format(
215 import WebBrowser.WebBrowserWindow 216 Preferences.getWebBrowser("VirusTotalServiceKey"), scanId
216 nam = ( 217 ).encode("utf-8")
217 WebBrowser.WebBrowserWindow.WebBrowserWindow.networkManager() 218 )
218 ) 219
220 import WebBrowser.WebBrowserWindow
221
222 nam = WebBrowser.WebBrowserWindow.WebBrowserWindow.networkManager()
219 reply = nam.post(request, params) 223 reply = nam.post(request, params)
220 reply.finished.connect( 224 reply.finished.connect(lambda: self.__getUrlScanReportUrlFinished(reply))
221 lambda: self.__getUrlScanReportUrlFinished(reply)) 225 self.__replies.append(reply)
222 self.__replies.append(reply) 226
223
224 def __getUrlScanReportUrlFinished(self, reply): 227 def __getUrlScanReportUrlFinished(self, reply):
225 """ 228 """
226 Private slot to determine the result of the URL scan report URL. 229 Private slot to determine the result of the URL scan report URL.
227 230
228 @param reply reference to the network reply 231 @param reply reference to the network reply
229 @type QNetworkReply 232 @type QNetworkReply
230 request. 233 request.
231 """ 234 """
232 if reply.error() == QNetworkReply.NetworkError.NoError: 235 if reply.error() == QNetworkReply.NetworkError.NoError:
233 result = json.loads(str(reply.readAll(), "utf-8")) 236 result = json.loads(str(reply.readAll(), "utf-8"))
234 if "filescan_id" in result and result["filescan_id"] is not None: 237 if "filescan_id" in result and result["filescan_id"] is not None:
235 self.__getFileScanReportUrl(result["filescan_id"]) 238 self.__getFileScanReportUrl(result["filescan_id"])
236 self.__replies.remove(reply) 239 self.__replies.remove(reply)
237 reply.deleteLater() 240 reply.deleteLater()
238 241
239 def __getFileScanReportUrl(self, scanId): 242 def __getFileScanReportUrl(self, scanId):
240 """ 243 """
241 Private method to get the report URL for a file scan. 244 Private method to get the report URL for a file scan.
242 245
243 @param scanId ID of the scan to get the report URL for (string) 246 @param scanId ID of the scan to get the report URL for (string)
244 """ 247 """
245 request = QNetworkRequest(QUrl(self.GetFileReportUrl)) 248 request = QNetworkRequest(QUrl(self.GetFileReportUrl))
246 request.setHeader(QNetworkRequest.KnownHeaders.ContentTypeHeader, 249 request.setHeader(
247 "application/x-www-form-urlencoded") 250 QNetworkRequest.KnownHeaders.ContentTypeHeader,
248 params = QByteArray("apikey={0}&resource={1}".format( 251 "application/x-www-form-urlencoded",
249 Preferences.getWebBrowser("VirusTotalServiceKey"), scanId) 252 )
250 .encode("utf-8")) 253 params = QByteArray(
251 254 "apikey={0}&resource={1}".format(
252 import WebBrowser.WebBrowserWindow 255 Preferences.getWebBrowser("VirusTotalServiceKey"), scanId
253 nam = ( 256 ).encode("utf-8")
254 WebBrowser.WebBrowserWindow.WebBrowserWindow.networkManager() 257 )
255 ) 258
259 import WebBrowser.WebBrowserWindow
260
261 nam = WebBrowser.WebBrowserWindow.WebBrowserWindow.networkManager()
256 reply = nam.post(request, params) 262 reply = nam.post(request, params)
257 reply.finished.connect( 263 reply.finished.connect(lambda: self.__getFileScanReportUrlFinished(reply))
258 lambda: self.__getFileScanReportUrlFinished(reply)) 264 self.__replies.append(reply)
259 self.__replies.append(reply) 265
260
261 def __getFileScanReportUrlFinished(self, reply): 266 def __getFileScanReportUrlFinished(self, reply):
262 """ 267 """
263 Private slot to determine the result of the file scan report URL 268 Private slot to determine the result of the file scan report URL
264 request. 269 request.
265 270
266 @param reply reference to the network reply 271 @param reply reference to the network reply
267 @type QNetworkReply 272 @type QNetworkReply
268 """ 273 """
269 if reply.error() == QNetworkReply.NetworkError.NoError: 274 if reply.error() == QNetworkReply.NetworkError.NoError:
270 result = json.loads(str(reply.readAll(), "utf-8")) 275 result = json.loads(str(reply.readAll(), "utf-8"))
271 self.fileScanReport.emit(result["permalink"]) 276 self.fileScanReport.emit(result["permalink"])
272 self.__replies.remove(reply) 277 self.__replies.remove(reply)
273 reply.deleteLater() 278 reply.deleteLater()
274 279
275 def getIpAddressReport(self, ipAddress): 280 def getIpAddressReport(self, ipAddress):
276 """ 281 """
277 Public method to retrieve a report for an IP address. 282 Public method to retrieve a report for an IP address.
278 283
279 @param ipAddress valid IPv4 address in dotted quad notation 284 @param ipAddress valid IPv4 address in dotted quad notation
280 @type str 285 @type str
281 """ 286 """
282 self.__lastIP = ipAddress 287 self.__lastIP = ipAddress
283 288
284 queryItems = [ 289 queryItems = [
285 ("apikey", Preferences.getWebBrowser("VirusTotalServiceKey")), 290 ("apikey", Preferences.getWebBrowser("VirusTotalServiceKey")),
286 ("ip", ipAddress), 291 ("ip", ipAddress),
287 ] 292 ]
288 url = QUrl(self.GetIpAddressReportUrl) 293 url = QUrl(self.GetIpAddressReportUrl)
289 query = QUrlQuery() 294 query = QUrlQuery()
290 query.setQueryItems(queryItems) 295 query.setQueryItems(queryItems)
291 url.setQuery(query) 296 url.setQuery(query)
292 request = QNetworkRequest(url) 297 request = QNetworkRequest(url)
293 298
294 import WebBrowser.WebBrowserWindow 299 import WebBrowser.WebBrowserWindow
295 nam = ( 300
296 WebBrowser.WebBrowserWindow.WebBrowserWindow.networkManager() 301 nam = WebBrowser.WebBrowserWindow.WebBrowserWindow.networkManager()
297 )
298 reply = nam.get(request) 302 reply = nam.get(request)
299 reply.finished.connect( 303 reply.finished.connect(lambda: self.__getIpAddressReportFinished(reply))
300 lambda: self.__getIpAddressReportFinished(reply)) 304 self.__replies.append(reply)
301 self.__replies.append(reply) 305
302
303 def __getIpAddressReportFinished(self, reply): 306 def __getIpAddressReportFinished(self, reply):
304 """ 307 """
305 Private slot to process the IP address report data. 308 Private slot to process the IP address report data.
306 309
307 @param reply reference to the network reply 310 @param reply reference to the network reply
308 @type QNetworkReply 311 @type QNetworkReply
309 """ 312 """
310 if reply.error() == QNetworkReply.NetworkError.NoError: 313 if reply.error() == QNetworkReply.NetworkError.NoError:
311 result = json.loads(str(reply.readAll(), "utf-8")) 314 result = json.loads(str(reply.readAll(), "utf-8"))
312 if result["response_code"] == 0: 315 if result["response_code"] == 0:
313 EricMessageBox.information( 316 EricMessageBox.information(
314 None, 317 None,
315 self.tr("VirusTotal IP Address Report"), 318 self.tr("VirusTotal IP Address Report"),
316 self.tr("""VirusTotal does not have any information for""" 319 self.tr(
317 """ the given IP address.""")) 320 """VirusTotal does not have any information for"""
321 """ the given IP address."""
322 ),
323 )
318 elif result["response_code"] == -1: 324 elif result["response_code"] == -1:
319 EricMessageBox.information( 325 EricMessageBox.information(
320 None, 326 None,
321 self.tr("VirusTotal IP Address Report"), 327 self.tr("VirusTotal IP Address Report"),
322 self.tr("""The submitted IP address is invalid.""")) 328 self.tr("""The submitted IP address is invalid."""),
329 )
323 else: 330 else:
324 owner = result["as_owner"] 331 owner = result["as_owner"]
325 resolutions = result["resolutions"] 332 resolutions = result["resolutions"]
326 try: 333 try:
327 urls = result["detected_urls"] 334 urls = result["detected_urls"]
328 except KeyError: 335 except KeyError:
329 urls = [] 336 urls = []
330 337
331 from .VirusTotalIpReportDialog import VirusTotalIpReportDialog 338 from .VirusTotalIpReportDialog import VirusTotalIpReportDialog
339
332 self.__ipReportDlg = VirusTotalIpReportDialog( 340 self.__ipReportDlg = VirusTotalIpReportDialog(
333 self.__lastIP, owner, resolutions, urls) 341 self.__lastIP, owner, resolutions, urls
342 )
334 self.__ipReportDlg.show() 343 self.__ipReportDlg.show()
335 self.__replies.remove(reply) 344 self.__replies.remove(reply)
336 reply.deleteLater() 345 reply.deleteLater()
337 346
338 def getDomainReport(self, domain): 347 def getDomainReport(self, domain):
339 """ 348 """
340 Public method to retrieve a report for a domain. 349 Public method to retrieve a report for a domain.
341 350
342 @param domain domain name 351 @param domain domain name
343 @type str 352 @type str
344 """ 353 """
345 self.__lastDomain = domain 354 self.__lastDomain = domain
346 355
347 queryItems = [ 356 queryItems = [
348 ("apikey", Preferences.getWebBrowser("VirusTotalServiceKey")), 357 ("apikey", Preferences.getWebBrowser("VirusTotalServiceKey")),
349 ("domain", domain), 358 ("domain", domain),
350 ] 359 ]
351 url = QUrl(self.GetDomainReportUrl) 360 url = QUrl(self.GetDomainReportUrl)
352 query = QUrlQuery() 361 query = QUrlQuery()
353 query.setQueryItems(queryItems) 362 query.setQueryItems(queryItems)
354 url.setQuery(query) 363 url.setQuery(query)
355 request = QNetworkRequest(url) 364 request = QNetworkRequest(url)
356 365
357 import WebBrowser.WebBrowserWindow 366 import WebBrowser.WebBrowserWindow
358 nam = ( 367
359 WebBrowser.WebBrowserWindow.WebBrowserWindow.networkManager() 368 nam = WebBrowser.WebBrowserWindow.WebBrowserWindow.networkManager()
360 )
361 reply = nam.get(request) 369 reply = nam.get(request)
362 reply.finished.connect(lambda: self.__getDomainReportFinished(reply)) 370 reply.finished.connect(lambda: self.__getDomainReportFinished(reply))
363 self.__replies.append(reply) 371 self.__replies.append(reply)
364 372
365 def __getDomainReportFinished(self, reply): 373 def __getDomainReportFinished(self, reply):
366 """ 374 """
367 Private slot to process the IP address report data. 375 Private slot to process the IP address report data.
368 376
369 @param reply reference to the network reply 377 @param reply reference to the network reply
370 @type QNetworkReply 378 @type QNetworkReply
371 """ 379 """
372 if reply.error() == QNetworkReply.NetworkError.NoError: 380 if reply.error() == QNetworkReply.NetworkError.NoError:
373 result = json.loads(str(reply.readAll(), "utf-8")) 381 result = json.loads(str(reply.readAll(), "utf-8"))
374 if result["response_code"] == 0: 382 if result["response_code"] == 0:
375 EricMessageBox.information( 383 EricMessageBox.information(
376 None, 384 None,
377 self.tr("VirusTotal Domain Report"), 385 self.tr("VirusTotal Domain Report"),
378 self.tr("""VirusTotal does not have any information for""" 386 self.tr(
379 """ the given domain.""")) 387 """VirusTotal does not have any information for"""
388 """ the given domain."""
389 ),
390 )
380 elif result["response_code"] == -1: 391 elif result["response_code"] == -1:
381 EricMessageBox.information( 392 EricMessageBox.information(
382 None, 393 None,
383 self.tr("VirusTotal Domain Report"), 394 self.tr("VirusTotal Domain Report"),
384 self.tr("""The submitted domain address is invalid.""")) 395 self.tr("""The submitted domain address is invalid."""),
396 )
385 else: 397 else:
386 resolutions = result["resolutions"] 398 resolutions = result["resolutions"]
387 try: 399 try:
388 urls = result["detected_urls"] 400 urls = result["detected_urls"]
389 except KeyError: 401 except KeyError:
390 urls = [] 402 urls = []
391 try: 403 try:
392 subdomains = result["subdomains"] 404 subdomains = result["subdomains"]
393 except KeyError: 405 except KeyError:
394 subdomains = [] 406 subdomains = []
395 407
396 categoriesMapping = { 408 categoriesMapping = {
397 "bitdefender": ("BitDefender category",), 409 "bitdefender": ("BitDefender category",),
398 "sophos": ("sophos category", "Sophos category"), 410 "sophos": ("sophos category", "Sophos category"),
399 "valkyrie": ("Comodo Valkyrie Verdict category",), 411 "valkyrie": ("Comodo Valkyrie Verdict category",),
400 "alpha": ("alphaMountain.ai category",), 412 "alpha": ("alphaMountain.ai category",),
410 categories[key] = "--" 422 categories[key] = "--"
411 try: 423 try:
412 whois = result["whois"] 424 whois = result["whois"]
413 except KeyError: 425 except KeyError:
414 whois = "" 426 whois = ""
415 427
416 webutationData = { 428 webutationData = {"adult": "--", "safety": "--", "verdict": "--"}
417 "adult": "--",
418 "safety": "--",
419 "verdict": "--"
420 }
421 with contextlib.suppress(KeyError): 429 with contextlib.suppress(KeyError):
422 webutation = result["Webutation domain info"] 430 webutation = result["Webutation domain info"]
423 with contextlib.suppress(KeyError): 431 with contextlib.suppress(KeyError):
424 webutationData["adult"] = webutation["Adult content"] 432 webutationData["adult"] = webutation["Adult content"]
425 with contextlib.suppress(KeyError): 433 with contextlib.suppress(KeyError):
426 webutationData["safety"] = webutation["Safety score"] 434 webutationData["safety"] = webutation["Safety score"]
427 with contextlib.suppress(KeyError): 435 with contextlib.suppress(KeyError):
428 webutationData["verdict"] = webutation["Verdict"] 436 webutationData["verdict"] = webutation["Verdict"]
429 437
430 from .VirusTotalDomainReportDialog import ( 438 from .VirusTotalDomainReportDialog import VirusTotalDomainReportDialog
431 VirusTotalDomainReportDialog 439
432 )
433 self.__domainReportDlg = VirusTotalDomainReportDialog( 440 self.__domainReportDlg = VirusTotalDomainReportDialog(
434 self.__lastDomain, resolutions, urls, subdomains, 441 self.__lastDomain,
435 categories, webutationData, whois) 442 resolutions,
443 urls,
444 subdomains,
445 categories,
446 webutationData,
447 whois,
448 )
436 self.__domainReportDlg.show() 449 self.__domainReportDlg.show()
437 self.__replies.remove(reply) 450 self.__replies.remove(reply)
438 reply.deleteLater() 451 reply.deleteLater()
439 452
440 def close(self): 453 def close(self):
441 """ 454 """
442 Public slot to close the API. 455 Public slot to close the API.
443 """ 456 """
444 for reply in self.__replies: 457 for reply in self.__replies:
445 reply.abort() 458 reply.abort()
446 459
447 self.__ipReportDlg and self.__ipReportDlg.close() 460 self.__ipReportDlg and self.__ipReportDlg.close()
448 self.__domainReportDlg and self.__domainReportDlg.close() 461 self.__domainReportDlg and self.__domainReportDlg.close()

eric ide

mercurial