Helpviewer/VirusTotalApi.py

changeset 979
0ae0c8852d31
parent 978
11f8adbcac97
child 992
566e87428fc8
diff -r 11f8adbcac97 -r 0ae0c8852d31 Helpviewer/VirusTotalApi.py
--- a/Helpviewer/VirusTotalApi.py	Sun Apr 10 18:33:20 2011 +0200
+++ b/Helpviewer/VirusTotalApi.py	Mon Apr 11 20:06:15 2011 +0200
@@ -9,7 +9,7 @@
 
 import json
 
-from PyQt4.QtCore import QObject, QUrl, QByteArray, QCoreApplication, QThread
+from PyQt4.QtCore import QObject, QUrl, QByteArray, pyqtSignal
 from PyQt4.QtNetwork import QNetworkRequest, QNetworkReply, QNetworkAccessManager
 
 import Helpviewer.HelpWindow
@@ -19,7 +19,20 @@
 class VirusTotalAPI(QObject):
     """
     Class implementing the <a href="http://www.virustotal.com">VirusTotal</a> API.
+    
+    @signal checkServiceKeyFinished(bool, str) emitted after the service key check
+            has been performed. It gives a flag indicating validity (boolean) and
+            an error message in case of a network error (string).
+    @signal submitUrlError(str) emitted with the error string, if the URL scan
+            submission returned an error. 
+    @signal urlScanReport(str) emitted with the URL of the URL scan report page
+    @signal fileScanReport(str) emitted with the URL of the file scan report page
     """
+    checkServiceKeyFinished = pyqtSignal(bool, str)
+    submitUrlError = pyqtSignal(str)
+    urlScanReport = pyqtSignal(str)
+    fileScanReport = pyqtSignal(str)
+    
     TestServiceKeyScanID = \
         "4feed2c2e352f105f6188efd1d5a558f24aee6971bdf96d5fdb19c197d6d3fad"
     
@@ -45,6 +58,8 @@
         """
         QObject.__init__(self, parent)
         
+        self.__replies = []
+        
         self.__loadSettings()
     
     def __loadSettings(self):
@@ -65,6 +80,12 @@
              0: self.trUtf8("Requested item is not present.")
         }
     
+    def preferencesChanged(self):
+        """
+        Public slot to handle a change of preferences.
+        """
+        self.__loadSettings()
+    
     def checkServiceKeyValidity(self, key, protocol=""):
         """
         Public method to check the validity of the given service key.
@@ -86,20 +107,26 @@
         
         nam = Helpviewer.HelpWindow.HelpWindow.networkAccessManager()
         reply = nam.post(request, params)
-        while not reply.isFinished():
-            QCoreApplication.processEvents()
-            QThread.msleep(100)
-            if QCoreApplication.closingDown():
-                reply.abort()
-            QCoreApplication.processEvents()
+        reply.finished.connect(self.__checkServiceKeyValidityFinished)
+        self.__replies.append(reply)
+    
+    def __checkServiceKeyValidityFinished(self):
+        """
+        Private slot to determine the result of the service key validity check.
+        """
+        res = False
+        msg = ""
+        
+        reply = self.sender()
         if reply.error() == QNetworkReply.NoError:
             result = json.loads(str(reply.readAll(), "utf-8"))
             if result["result"] != self.ServiceResult_InvalidServiceKey:
-                return True, ""
-            else:
-                return False, ""
+                res = True
+        else:
+            msg = reply.errorString()
+        self.__replies.remove(reply)
         
-        return False, reply.errorString()
+        self.checkServiceKeyFinished.emit(res, msg)
     
     def submitUrl(self, url):
         """
@@ -117,39 +144,33 @@
         
         nam = Helpviewer.HelpWindow.HelpWindow.networkAccessManager()
         reply = nam.post(request, params)
-        while not reply.isFinished():
-            QCoreApplication.processEvents()
-            QThread.msleep(100)
-            if QCoreApplication.closingDown():
-                reply.abort()
-            QCoreApplication.processEvents()
+        reply.finished.connect(self.__submitUrlFinished)
+        self.__replies.append(reply)
+    
+    def __submitUrlFinished(self):
+        """
+        Private slot to determine the result of the URL scan submission.
+        """
+        reply = self.sender()
         if reply.error() == QNetworkReply.NoError:
             result = json.loads(str(reply.readAll(), "utf-8"))
             if result["result"] == self.ServiceResult_ItemPresent:
-                return True, result["scan_id"]
+                self.urlScanReport.emit(
+                    self.ReportUrlScanPagePattern.format(result["scan_id"]))
+                self.__getFileScanReportUrl(result["scan_id"])
             else:
-                return False, self.errorMessages[result["result"]]
-        
-        return False, reply.errorString()
+                self.submitUrlError.emit(self.errorMessages[result["result"]])
+        else:
+            self.submitUrlError.emit(reply.errorString())
+        self.__replies.remove(reply)
     
-    def getUrlScanReportUrl(self, scanId):
+    def __getFileScanReportUrl(self, scanId):
         """
-        Public method to get the report URL for a URL scan.
-        
-        @param scanId ID of the scan to get the report URL for (string)
-        @return URL scan report URL (string)
-        """
-        return self.ReportUrlScanPagePattern.format(scanId)
-        
-    def getFileScanReportUrl(self, scanId):
-        """
-        Public method to get the report URL for a file scan.
+        Private method to get the report URL for a file scan.
         
         @param scanId ID of the scan to get the report URL for (string)
         @return file scan report URL (string)
         """
-        fileScanPageUrl = ""    # default value
-        
         request = QNetworkRequest(QUrl(self.GetUrlReportUrl))
         request.setHeader(QNetworkRequest.ContentTypeHeader,
                           "application/x-www-form-urlencoded")
@@ -158,24 +179,29 @@
         
         nam = Helpviewer.HelpWindow.HelpWindow.networkAccessManager()
         reply = nam.post(request, params)
-        while not reply.isFinished():
-            QCoreApplication.processEvents()
-            QThread.msleep(100)
-            if QCoreApplication.closingDown():
-                reply.abort()
-            QCoreApplication.processEvents()
+        reply.finished.connect(self.__getFileScanReportUrlFinished)
+        self.__replies.append(reply)
+    
+    def __getFileScanReportUrlFinished(self):
+        """
+        Private slot to determine the result of the file scan report URL request.
+        """
+        reply = self.sender()
         if reply.error() == QNetworkReply.NoError:
             result = json.loads(str(reply.readAll(), "utf-8"))
             if "file-report" in result:
-                fileScanPageUrl = self.ReportFileScanPagePattern.format(
-                    result["file-report"])
-        
-        return fileScanPageUrl
+                self.fileScanReport.emit(
+                    self.ReportFileScanPagePattern.format(result["file-report"]))
+        self.__replies.remove(reply)
     
     @classmethod
     def getSearchRequestData(cls, term):
         """
+        Class method to assemble the search request data structure.
         
+        @param term search term (string)
+        @return tuple of network request object, operation and parameters
+            (QNetworkRequest, QNetworkAccessManager.Operation, QByteArray)
         """
         request = QNetworkRequest(QUrl(cls.SearchUrl))
         request.setHeader(QNetworkRequest.ContentTypeHeader,

eric ide

mercurial