Sat, 25 Jul 2015 20:00:25 +0200
Started implementing the VirusTotal APIv2 interface.
--- a/APIs/Python3/eric6.api Sat Jul 25 18:22:34 2015 +0200 +++ b/APIs/Python3/eric6.api Sat Jul 25 20:00:25 2015 +0200 @@ -3332,26 +3332,31 @@ eric6.Helpviewer.UserAgent.UserAgentWriter.UserAgentWriter.write?4(fileNameOrDevice, agents) eric6.Helpviewer.UserAgent.UserAgentWriter.UserAgentWriter?1() eric6.Helpviewer.UserAgent.UserAgentsDialog.UserAgentsDialog?1(parent=None) +eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.GetDomainReportPattern?7 eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.GetFileReportPattern?7 +eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.GetIpAddressReportPattern?7 eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.GetUrlReportPattern?7 -eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.ReportFileScanPagePattern?7 -eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.ReportUrlScanPagePattern?7 eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.ScanUrlPattern?7 -eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.SearchUrl?7 -eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.ServiceResult_InvalidServiceKey?7 +eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.ServiceCode_InvalidKey?7 +eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.ServiceCode_InvalidPrivilege?7 +eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.ServiceCode_RateLimitExceeded?7 eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.ServiceResult_ItemNotPresent?7 eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.ServiceResult_ItemPresent?7 -eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.ServiceResult_RequestLimitReached?7 +eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.ServiceResult_ItemQueued?7 eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.TestServiceKeyScanID?7 eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.checkServiceKeyFinished?7 eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.checkServiceKeyValidity?4(key, protocol="") +eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.close?4() eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.fileScanReport?7 -eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.getSearchRequestData?4(term) +eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.getDomainReport?4(domain) +eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.getIpAddressReport?4(ipAddress) eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.preferencesChanged?4() eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.submitUrl?4(url) eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.submitUrlError?7 eric6.Helpviewer.VirusTotalApi.VirusTotalAPI.urlScanReport?7 eric6.Helpviewer.VirusTotalApi.VirusTotalAPI?1(parent=None) +eric6.Helpviewer.VirusTotalDomainReportDialog.VirusTotalDomainReportDialog?1(domain, resolutions, urls, subdomains, bdCategory, tmCategory, wtsCategory, categories, parent=None) +eric6.Helpviewer.VirusTotalIpReportDialog.VirusTotalIpReportDialog?1(ip, owner, resolutions, urls, parent=None) eric6.Helpviewer.WebPlugins.ClickToFlash.ClickToFlash.ClickToFlash._acceptedArgNames?8 eric6.Helpviewer.WebPlugins.ClickToFlash.ClickToFlash.ClickToFlash._acceptedArgValues?8 eric6.Helpviewer.WebPlugins.ClickToFlash.ClickToFlash.ClickToFlash._acceptedUrl?8
--- a/APIs/Python3/eric6.bas Sat Jul 25 18:22:34 2015 +0200 +++ b/APIs/Python3/eric6.bas Sat Jul 25 20:00:25 2015 +0200 @@ -779,6 +779,8 @@ ViewProfileDialog QDialog ViewmanagerPage ConfigurationPageBase Ui_ViewmanagerPage VirusTotalAPI QObject +VirusTotalDomainReportDialog QDialog Ui_VirusTotalDomainReportDialog +VirusTotalIpReportDialog QDialog Ui_VirusTotalIpReportDialog VisibilityMixin ClbrBaseClasses.ClbrVisibilityMixinBase VmListspacePlugin QObject VmTabviewPlugin QObject
--- a/Documentation/Help/source.qhp Sat Jul 25 18:22:34 2015 +0200 +++ b/Documentation/Help/source.qhp Sat Jul 25 20:00:25 2015 +0200 @@ -417,6 +417,8 @@ <section title="eric6.Helpviewer.QtHelpFiltersDialog" ref="eric6.Helpviewer.QtHelpFiltersDialog.html" /> <section title="eric6.Helpviewer.SearchWidget" ref="eric6.Helpviewer.SearchWidget.html" /> <section title="eric6.Helpviewer.VirusTotalApi" ref="eric6.Helpviewer.VirusTotalApi.html" /> + <section title="eric6.Helpviewer.VirusTotalDomainReportDialog" ref="eric6.Helpviewer.VirusTotalDomainReportDialog.html" /> + <section title="eric6.Helpviewer.VirusTotalIpReportDialog" ref="eric6.Helpviewer.VirusTotalIpReportDialog.html" /> </section> <section title="eric6.IconEditor" ref="index-eric6.IconEditor.html"> <section title="eric6.IconEditor.cursors" ref="index-eric6.IconEditor.cursors.html"> @@ -5650,10 +5652,10 @@ <keyword name="HelpWindow.__titleChanged" id="HelpWindow.__titleChanged" ref="eric6.Helpviewer.HelpWindow.html#HelpWindow.__titleChanged" /> <keyword name="HelpWindow.__userStyleSheet" id="HelpWindow.__userStyleSheet" ref="eric6.Helpviewer.HelpWindow.html#HelpWindow.__userStyleSheet" /> <keyword name="HelpWindow.__viewFullScreen" id="HelpWindow.__viewFullScreen" ref="eric6.Helpviewer.HelpWindow.html#HelpWindow.__viewFullScreen" /> + <keyword name="HelpWindow.__virusTotalDomainReport" id="HelpWindow.__virusTotalDomainReport" ref="eric6.Helpviewer.HelpWindow.html#HelpWindow.__virusTotalDomainReport" /> <keyword name="HelpWindow.__virusTotalFileScanReport" id="HelpWindow.__virusTotalFileScanReport" ref="eric6.Helpviewer.HelpWindow.html#HelpWindow.__virusTotalFileScanReport" /> + <keyword name="HelpWindow.__virusTotalIpAddressReport" id="HelpWindow.__virusTotalIpAddressReport" ref="eric6.Helpviewer.HelpWindow.html#HelpWindow.__virusTotalIpAddressReport" /> <keyword name="HelpWindow.__virusTotalScanCurrentSite" id="HelpWindow.__virusTotalScanCurrentSite" ref="eric6.Helpviewer.HelpWindow.html#HelpWindow.__virusTotalScanCurrentSite" /> - <keyword name="HelpWindow.__virusTotalSearch" id="HelpWindow.__virusTotalSearch" ref="eric6.Helpviewer.HelpWindow.html#HelpWindow.__virusTotalSearch" /> - <keyword name="HelpWindow.__virusTotalSearchChanged" id="HelpWindow.__virusTotalSearchChanged" ref="eric6.Helpviewer.HelpWindow.html#HelpWindow.__virusTotalSearchChanged" /> <keyword name="HelpWindow.__virusTotalSubmitUrlError" id="HelpWindow.__virusTotalSubmitUrlError" ref="eric6.Helpviewer.HelpWindow.html#HelpWindow.__virusTotalSubmitUrlError" /> <keyword name="HelpWindow.__virusTotalUrlScanReport" id="HelpWindow.__virusTotalUrlScanReport" ref="eric6.Helpviewer.HelpWindow.html#HelpWindow.__virusTotalUrlScanReport" /> <keyword name="HelpWindow.__warning" id="HelpWindow.__warning" ref="eric6.Helpviewer.HelpWindow.html#HelpWindow.__warning" /> @@ -12901,15 +12903,27 @@ <keyword name="VirusTotalAPI" id="VirusTotalAPI" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI" /> <keyword name="VirusTotalAPI (Constructor)" id="VirusTotalAPI (Constructor)" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.__init__" /> <keyword name="VirusTotalAPI.__checkServiceKeyValidityFinished" id="VirusTotalAPI.__checkServiceKeyValidityFinished" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.__checkServiceKeyValidityFinished" /> + <keyword name="VirusTotalAPI.__getDomainReportFinished" id="VirusTotalAPI.__getDomainReportFinished" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.__getDomainReportFinished" /> <keyword name="VirusTotalAPI.__getFileScanReportUrl" id="VirusTotalAPI.__getFileScanReportUrl" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.__getFileScanReportUrl" /> <keyword name="VirusTotalAPI.__getFileScanReportUrlFinished" id="VirusTotalAPI.__getFileScanReportUrlFinished" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.__getFileScanReportUrlFinished" /> + <keyword name="VirusTotalAPI.__getIpAddressReportFinished" id="VirusTotalAPI.__getIpAddressReportFinished" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.__getIpAddressReportFinished" /> + <keyword name="VirusTotalAPI.__getUrlScanReportUrl" id="VirusTotalAPI.__getUrlScanReportUrl" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.__getUrlScanReportUrl" /> + <keyword name="VirusTotalAPI.__getUrlScanReportUrlFinished" id="VirusTotalAPI.__getUrlScanReportUrlFinished" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.__getUrlScanReportUrlFinished" /> <keyword name="VirusTotalAPI.__loadSettings" id="VirusTotalAPI.__loadSettings" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.__loadSettings" /> <keyword name="VirusTotalAPI.__submitUrlFinished" id="VirusTotalAPI.__submitUrlFinished" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.__submitUrlFinished" /> <keyword name="VirusTotalAPI.checkServiceKeyValidity" id="VirusTotalAPI.checkServiceKeyValidity" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.checkServiceKeyValidity" /> - <keyword name="VirusTotalAPI.getSearchRequestData" id="VirusTotalAPI.getSearchRequestData" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.getSearchRequestData" /> + <keyword name="VirusTotalAPI.close" id="VirusTotalAPI.close" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.close" /> + <keyword name="VirusTotalAPI.getDomainReport" id="VirusTotalAPI.getDomainReport" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.getDomainReport" /> + <keyword name="VirusTotalAPI.getIpAddressReport" id="VirusTotalAPI.getIpAddressReport" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.getIpAddressReport" /> <keyword name="VirusTotalAPI.preferencesChanged" id="VirusTotalAPI.preferencesChanged" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.preferencesChanged" /> <keyword name="VirusTotalAPI.submitUrl" id="VirusTotalAPI.submitUrl" ref="eric6.Helpviewer.VirusTotalApi.html#VirusTotalAPI.submitUrl" /> <keyword name="VirusTotalApi (Module)" id="VirusTotalApi (Module)" ref="eric6.Helpviewer.VirusTotalApi.html" /> + <keyword name="VirusTotalDomainReportDialog" id="VirusTotalDomainReportDialog" ref="eric6.Helpviewer.VirusTotalDomainReportDialog.html#VirusTotalDomainReportDialog" /> + <keyword name="VirusTotalDomainReportDialog (Constructor)" id="VirusTotalDomainReportDialog (Constructor)" ref="eric6.Helpviewer.VirusTotalDomainReportDialog.html#VirusTotalDomainReportDialog.__init__" /> + <keyword name="VirusTotalDomainReportDialog (Module)" id="VirusTotalDomainReportDialog (Module)" ref="eric6.Helpviewer.VirusTotalDomainReportDialog.html" /> + <keyword name="VirusTotalIpReportDialog" id="VirusTotalIpReportDialog" ref="eric6.Helpviewer.VirusTotalIpReportDialog.html#VirusTotalIpReportDialog" /> + <keyword name="VirusTotalIpReportDialog (Constructor)" id="VirusTotalIpReportDialog (Constructor)" ref="eric6.Helpviewer.VirusTotalIpReportDialog.html#VirusTotalIpReportDialog.__init__" /> + <keyword name="VirusTotalIpReportDialog (Module)" id="VirusTotalIpReportDialog (Module)" ref="eric6.Helpviewer.VirusTotalIpReportDialog.html" /> <keyword name="VisibilityBase" id="VisibilityBase" ref="eric6.Utilities.ModuleParser.html#VisibilityBase" /> <keyword name="VisibilityBase.isPrivate" id="VisibilityBase.isPrivate" ref="eric6.Utilities.ModuleParser.html#VisibilityBase.isPrivate" /> <keyword name="VisibilityBase.isProtected" id="VisibilityBase.isProtected" ref="eric6.Utilities.ModuleParser.html#VisibilityBase.isProtected" /> @@ -14149,6 +14163,8 @@ <file>eric6.Helpviewer.UserAgent.UserAgentWriter.html</file> <file>eric6.Helpviewer.UserAgent.UserAgentsDialog.html</file> <file>eric6.Helpviewer.VirusTotalApi.html</file> + <file>eric6.Helpviewer.VirusTotalDomainReportDialog.html</file> + <file>eric6.Helpviewer.VirusTotalIpReportDialog.html</file> <file>eric6.Helpviewer.WebPlugins.ClickToFlash.ClickToFlash.html</file> <file>eric6.Helpviewer.WebPlugins.ClickToFlash.ClickToFlashPlugin.html</file> <file>eric6.Helpviewer.WebPlugins.ClickToFlash.ClickToFlashWhitelistDialog.html</file>
--- a/Documentation/Source/eric6.Helpviewer.HelpUtilities.html Sat Jul 25 18:22:34 2015 +0200 +++ b/Documentation/Source/eric6.Helpviewer.HelpUtilities.html Sat Jul 25 20:00:25 2015 +0200 @@ -116,6 +116,16 @@ <dd> network reply to be parsed </dd> +</dl><dl> +<dt>Returns:</dt> +<dd> +file name parsed from a content disposition header +</dd> +</dl><dl> +<dt>Return Type:</dt> +<dd> +str +</dd> </dl> <div align="right"><a href="#top">Up</a></div> <hr />
--- a/Documentation/Source/eric6.Helpviewer.HelpWindow.html Sat Jul 25 18:22:34 2015 +0200 +++ b/Documentation/Source/eric6.Helpviewer.HelpWindow.html Sat Jul 25 20:00:25 2015 +0200 @@ -385,18 +385,18 @@ <td><a href="#HelpWindow.__viewFullScreen">__viewFullScreen</a></td> <td>Private slot called to toggle fullscreen mode.</td> </tr><tr> +<td><a href="#HelpWindow.__virusTotalDomainReport">__virusTotalDomainReport</a></td> +<td>Private slot to retrieve a domain report.</td> +</tr><tr> <td><a href="#HelpWindow.__virusTotalFileScanReport">__virusTotalFileScanReport</a></td> <td>Private slot to initiate the display of the file scan report page.</td> </tr><tr> +<td><a href="#HelpWindow.__virusTotalIpAddressReport">__virusTotalIpAddressReport</a></td> +<td>Private slot to retrieve an IP address report.</td> +</tr><tr> <td><a href="#HelpWindow.__virusTotalScanCurrentSite">__virusTotalScanCurrentSite</a></td> <td>Private slot to ask VirusTotal for a scan of the URL of the current browser.</td> </tr><tr> -<td><a href="#HelpWindow.__virusTotalSearch">__virusTotalSearch</a></td> -<td>Private slot to search VirusTotal for a given entry.</td> -</tr><tr> -<td><a href="#HelpWindow.__virusTotalSearchChanged">__virusTotalSearchChanged</a></td> -<td>Private slot to react upon changes of the VirusTotal search text.</td> -</tr><tr> <td><a href="#HelpWindow.__virusTotalSubmitUrlError">__virusTotalSubmitUrlError</a></td> <td>Private slot to handle an URL scan submission error.</td> </tr><tr> @@ -1293,6 +1293,11 @@ <b>__viewFullScreen</b>(<i></i>) <p> Private slot called to toggle fullscreen mode. +</p><a NAME="HelpWindow.__virusTotalDomainReport" ID="HelpWindow.__virusTotalDomainReport"></a> +<h4>HelpWindow.__virusTotalDomainReport</h4> +<b>__virusTotalDomainReport</b>(<i></i>) +<p> + Private slot to retrieve a domain report. </p><a NAME="HelpWindow.__virusTotalFileScanReport" ID="HelpWindow.__virusTotalFileScanReport"></a> <h4>HelpWindow.__virusTotalFileScanReport</h4> <b>__virusTotalFileScanReport</b>(<i>url</i>) @@ -1303,28 +1308,18 @@ <dd> URL of the file scan report page (string) </dd> -</dl><a NAME="HelpWindow.__virusTotalScanCurrentSite" ID="HelpWindow.__virusTotalScanCurrentSite"></a> +</dl><a NAME="HelpWindow.__virusTotalIpAddressReport" ID="HelpWindow.__virusTotalIpAddressReport"></a> +<h4>HelpWindow.__virusTotalIpAddressReport</h4> +<b>__virusTotalIpAddressReport</b>(<i></i>) +<p> + Private slot to retrieve an IP address report. +</p><a NAME="HelpWindow.__virusTotalScanCurrentSite" ID="HelpWindow.__virusTotalScanCurrentSite"></a> <h4>HelpWindow.__virusTotalScanCurrentSite</h4> <b>__virusTotalScanCurrentSite</b>(<i></i>) <p> Private slot to ask VirusTotal for a scan of the URL of the current browser. -</p><a NAME="HelpWindow.__virusTotalSearch" ID="HelpWindow.__virusTotalSearch"></a> -<h4>HelpWindow.__virusTotalSearch</h4> -<b>__virusTotalSearch</b>(<i></i>) -<p> - Private slot to search VirusTotal for a given entry. -</p><a NAME="HelpWindow.__virusTotalSearchChanged" ID="HelpWindow.__virusTotalSearchChanged"></a> -<h4>HelpWindow.__virusTotalSearchChanged</h4> -<b>__virusTotalSearchChanged</b>(<i>txt</i>) -<p> - Private slot to react upon changes of the VirusTotal search text. -</p><dl> -<dt><i>txt</i></dt> -<dd> -contents of the search (string) -</dd> -</dl><a NAME="HelpWindow.__virusTotalSubmitUrlError" ID="HelpWindow.__virusTotalSubmitUrlError"></a> +</p><a NAME="HelpWindow.__virusTotalSubmitUrlError" ID="HelpWindow.__virusTotalSubmitUrlError"></a> <h4>HelpWindow.__virusTotalSubmitUrlError</h4> <b>__virusTotalSubmitUrlError</b>(<i>msg</i>) <p>
--- a/Documentation/Source/eric6.Helpviewer.VirusTotalApi.html Sat Jul 25 18:22:34 2015 +0200 +++ b/Documentation/Source/eric6.Helpviewer.VirusTotalApi.html Sat Jul 25 20:00:25 2015 +0200 @@ -69,14 +69,11 @@ QObject <h3>Class Attributes</h3> <table> -<tr><td>GetFileReportPattern</td></tr><tr><td>GetUrlReportPattern</td></tr><tr><td>ReportFileScanPagePattern</td></tr><tr><td>ReportUrlScanPagePattern</td></tr><tr><td>ScanUrlPattern</td></tr><tr><td>SearchUrl</td></tr><tr><td>ServiceResult_InvalidServiceKey</td></tr><tr><td>ServiceResult_ItemNotPresent</td></tr><tr><td>ServiceResult_ItemPresent</td></tr><tr><td>ServiceResult_RequestLimitReached</td></tr><tr><td>TestServiceKeyScanID</td></tr> +<tr><td>GetDomainReportPattern</td></tr><tr><td>GetFileReportPattern</td></tr><tr><td>GetIpAddressReportPattern</td></tr><tr><td>GetUrlReportPattern</td></tr><tr><td>ScanUrlPattern</td></tr><tr><td>ServiceCode_InvalidKey</td></tr><tr><td>ServiceCode_InvalidPrivilege</td></tr><tr><td>ServiceCode_RateLimitExceeded</td></tr><tr><td>ServiceResult_ItemNotPresent</td></tr><tr><td>ServiceResult_ItemPresent</td></tr><tr><td>ServiceResult_ItemQueued</td></tr><tr><td>TestServiceKeyScanID</td></tr> </table> <h3>Class Methods</h3> <table> -<tr> -<td><a href="#VirusTotalAPI.getSearchRequestData">getSearchRequestData</a></td> -<td>Class method to assemble the search request data structure.</td> -</tr> +<tr><td>None</td></tr> </table> <h3>Methods</h3> <table> @@ -87,12 +84,24 @@ <td><a href="#VirusTotalAPI.__checkServiceKeyValidityFinished">__checkServiceKeyValidityFinished</a></td> <td>Private slot to determine the result of the service key validity check.</td> </tr><tr> +<td><a href="#VirusTotalAPI.__getDomainReportFinished">__getDomainReportFinished</a></td> +<td>Private slot to process the IP address report data.</td> +</tr><tr> <td><a href="#VirusTotalAPI.__getFileScanReportUrl">__getFileScanReportUrl</a></td> <td>Private method to get the report URL for a file scan.</td> </tr><tr> <td><a href="#VirusTotalAPI.__getFileScanReportUrlFinished">__getFileScanReportUrlFinished</a></td> <td>Private slot to determine the result of the file scan report URL request.</td> </tr><tr> +<td><a href="#VirusTotalAPI.__getIpAddressReportFinished">__getIpAddressReportFinished</a></td> +<td>Private slot to process the IP address report data.</td> +</tr><tr> +<td><a href="#VirusTotalAPI.__getUrlScanReportUrl">__getUrlScanReportUrl</a></td> +<td>Private method to get the report URL for a URL scan.</td> +</tr><tr> +<td><a href="#VirusTotalAPI.__getUrlScanReportUrlFinished">__getUrlScanReportUrlFinished</a></td> +<td>Private slot to determine the result of the URL scan report URL request.</td> +</tr><tr> <td><a href="#VirusTotalAPI.__loadSettings">__loadSettings</a></td> <td>Private method to load the settings.</td> </tr><tr> @@ -102,6 +111,15 @@ <td><a href="#VirusTotalAPI.checkServiceKeyValidity">checkServiceKeyValidity</a></td> <td>Public method to check the validity of the given service key.</td> </tr><tr> +<td><a href="#VirusTotalAPI.close">close</a></td> +<td>Public slot to close the API.</td> +</tr><tr> +<td><a href="#VirusTotalAPI.getDomainReport">getDomainReport</a></td> +<td>Public method to retrieve a report for a domain.</td> +</tr><tr> +<td><a href="#VirusTotalAPI.getIpAddressReport">getIpAddressReport</a></td> +<td>Public method to retrieve a report for an IP address.</td> +</tr><tr> <td><a href="#VirusTotalAPI.preferencesChanged">preferencesChanged</a></td> <td>Public slot to handle a change of preferences.</td> </tr><tr> @@ -113,23 +131,7 @@ <table> <tr><td>None</td></tr> </table> -<a NAME="VirusTotalAPI.getSearchRequestData" ID="VirusTotalAPI.getSearchRequestData"></a> -<h4>VirusTotalAPI.getSearchRequestData (class method)</h4> -<b>getSearchRequestData</b>(<i>term</i>) -<p> - Class method to assemble the search request data structure. -</p><dl> -<dt><i>term</i></dt> -<dd> -search term (string) -</dd> -</dl><dl> -<dt>Returns:</dt> -<dd> -tuple of network request object, operation and parameters - (QNetworkRequest, QNetworkAccessManager.Operation, QByteArray) -</dd> -</dl><a NAME="VirusTotalAPI.__init__" ID="VirusTotalAPI.__init__"></a> +<a NAME="VirusTotalAPI.__init__" ID="VirusTotalAPI.__init__"></a> <h4>VirusTotalAPI (Constructor)</h4> <b>VirusTotalAPI</b>(<i>parent=None</i>) <p> @@ -144,6 +146,11 @@ <b>__checkServiceKeyValidityFinished</b>(<i></i>) <p> Private slot to determine the result of the service key validity check. +</p><a NAME="VirusTotalAPI.__getDomainReportFinished" ID="VirusTotalAPI.__getDomainReportFinished"></a> +<h4>VirusTotalAPI.__getDomainReportFinished</h4> +<b>__getDomainReportFinished</b>(<i></i>) +<p> + Private slot to process the IP address report data. </p><a NAME="VirusTotalAPI.__getFileScanReportUrl" ID="VirusTotalAPI.__getFileScanReportUrl"></a> <h4>VirusTotalAPI.__getFileScanReportUrl</h4> <b>__getFileScanReportUrl</b>(<i>scanId</i>) @@ -160,6 +167,27 @@ <p> Private slot to determine the result of the file scan report URL request. +</p><a NAME="VirusTotalAPI.__getIpAddressReportFinished" ID="VirusTotalAPI.__getIpAddressReportFinished"></a> +<h4>VirusTotalAPI.__getIpAddressReportFinished</h4> +<b>__getIpAddressReportFinished</b>(<i></i>) +<p> + Private slot to process the IP address report data. +</p><a NAME="VirusTotalAPI.__getUrlScanReportUrl" ID="VirusTotalAPI.__getUrlScanReportUrl"></a> +<h4>VirusTotalAPI.__getUrlScanReportUrl</h4> +<b>__getUrlScanReportUrl</b>(<i>scanId</i>) +<p> + Private method to get the report URL for a URL scan. +</p><dl> +<dt><i>scanId</i></dt> +<dd> +ID of the scan to get the report URL for (string) +</dd> +</dl><a NAME="VirusTotalAPI.__getUrlScanReportUrlFinished" ID="VirusTotalAPI.__getUrlScanReportUrlFinished"></a> +<h4>VirusTotalAPI.__getUrlScanReportUrlFinished</h4> +<b>__getUrlScanReportUrlFinished</b>(<i></i>) +<p> + Private slot to determine the result of the URL scan report URL + request. </p><a NAME="VirusTotalAPI.__loadSettings" ID="VirusTotalAPI.__loadSettings"></a> <h4>VirusTotalAPI.__loadSettings</h4> <b>__loadSettings</b>(<i></i>) @@ -183,6 +211,31 @@ <dd> protocol used to access VirusTotal (string) </dd> +</dl><a NAME="VirusTotalAPI.close" ID="VirusTotalAPI.close"></a> +<h4>VirusTotalAPI.close</h4> +<b>close</b>(<i></i>) +<p> + Public slot to close the API. +</p><a NAME="VirusTotalAPI.getDomainReport" ID="VirusTotalAPI.getDomainReport"></a> +<h4>VirusTotalAPI.getDomainReport</h4> +<b>getDomainReport</b>(<i>domain</i>) +<p> + Public method to retrieve a report for a domain. +</p><dl> +<dt><i>domain</i> (str)</dt> +<dd> +domain name +</dd> +</dl><a NAME="VirusTotalAPI.getIpAddressReport" ID="VirusTotalAPI.getIpAddressReport"></a> +<h4>VirusTotalAPI.getIpAddressReport</h4> +<b>getIpAddressReport</b>(<i>ipAddress</i>) +<p> + Public method to retrieve a report for an IP address. +</p><dl> +<dt><i>ipAddress</i> (str)</dt> +<dd> +valid IPv4 address in dotted quad notation +</dd> </dl><a NAME="VirusTotalAPI.preferencesChanged" ID="VirusTotalAPI.preferencesChanged"></a> <h4>VirusTotalAPI.preferencesChanged</h4> <b>preferencesChanged</b>(<i></i>)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Documentation/Source/eric6.Helpviewer.VirusTotalDomainReportDialog.html Sat Jul 25 20:00:25 2015 +0200 @@ -0,0 +1,105 @@ +<!DOCTYPE html> +<html><head> +<title>eric6.Helpviewer.VirusTotalDomainReportDialog</title> +<meta charset="UTF-8"> +<style> +body { + background: #EDECE6; + margin: 0em 1em 10em 1em; + color: black; +} + +h1 { color: white; background: #85774A; } +h2 { color: white; background: #85774A; } +h3 { color: white; background: #9D936E; } +h4 { color: white; background: #9D936E; } + +a { color: #BA6D36; } + +</style> +</head> +<body><a NAME="top" ID="top"></a> +<h1>eric6.Helpviewer.VirusTotalDomainReportDialog</h1> +<p> +Module implementing a dialog to show the VirusTotal domain report. +</p> +<h3>Global Attributes</h3> +<table> +<tr><td>None</td></tr> +</table> +<h3>Classes</h3> +<table> +<tr> +<td><a href="#VirusTotalDomainReportDialog">VirusTotalDomainReportDialog</a></td> +<td>Class implementing a dialog to show the VirusTotal domain report.</td> +</tr> +</table> +<h3>Functions</h3> +<table> +<tr><td>None</td></tr> +</table> +<hr /><hr /> +<a NAME="VirusTotalDomainReportDialog" ID="VirusTotalDomainReportDialog"></a> +<h2>VirusTotalDomainReportDialog</h2> +<p> + Class implementing a dialog to show the VirusTotal domain report. +</p> +<h3>Derived from</h3> +QDialog, Ui_VirusTotalDomainReportDialog +<h3>Class Attributes</h3> +<table> +<tr><td>None</td></tr> +</table> +<h3>Class Methods</h3> +<table> +<tr><td>None</td></tr> +</table> +<h3>Methods</h3> +<table> +<tr> +<td><a href="#VirusTotalDomainReportDialog.__init__">VirusTotalDomainReportDialog</a></td> +<td>Constructor</td> +</tr> +</table> +<h3>Static Methods</h3> +<table> +<tr><td>None</td></tr> +</table> +<a NAME="VirusTotalDomainReportDialog.__init__" ID="VirusTotalDomainReportDialog.__init__"></a> +<h4>VirusTotalDomainReportDialog (Constructor)</h4> +<b>VirusTotalDomainReportDialog</b>(<i>domain, resolutions, urls, subdomains, bdCategory, tmCategory, wtsCategory, categories, parent=None</i>) +<p> + Constructor +</p><dl> +<dt><i>domain</i> (str)</dt> +<dd> +domain name +</dd><dt><i>resolutions</i> (list of dict)</dt> +<dd> +list of resolved host names +</dd><dt><i>urls</i> (list of dict)</dt> +<dd> +list of detected URLs +</dd><dt><i>subdomains</i> (list of str)</dt> +<dd> +list of subdomains +</dd><dt><i>bdCategory</i> (str)</dt> +<dd> +BitDefender categorization +</dd><dt><i>tmCategory</i> (str)</dt> +<dd> +TrendMicro categorization +</dd><dt><i>wtsCategory</i> (str)</dt> +<dd> +Websense ThreatSeeker categorization +</dd><dt><i>categories</i> (list of str)</dt> +<dd> +list of categorizations +</dd><dt><i>parent</i> (QWidget)</dt> +<dd> +reference to the parent widget +</dd> +</dl> +<div align="right"><a href="#top">Up</a></div> +<hr /> +</body></html> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Documentation/Source/eric6.Helpviewer.VirusTotalIpReportDialog.html Sat Jul 25 20:00:25 2015 +0200 @@ -0,0 +1,93 @@ +<!DOCTYPE html> +<html><head> +<title>eric6.Helpviewer.VirusTotalIpReportDialog</title> +<meta charset="UTF-8"> +<style> +body { + background: #EDECE6; + margin: 0em 1em 10em 1em; + color: black; +} + +h1 { color: white; background: #85774A; } +h2 { color: white; background: #85774A; } +h3 { color: white; background: #9D936E; } +h4 { color: white; background: #9D936E; } + +a { color: #BA6D36; } + +</style> +</head> +<body><a NAME="top" ID="top"></a> +<h1>eric6.Helpviewer.VirusTotalIpReportDialog</h1> +<p> +Module implementing a dialog to show the VirusTotal IP address report. +</p> +<h3>Global Attributes</h3> +<table> +<tr><td>None</td></tr> +</table> +<h3>Classes</h3> +<table> +<tr> +<td><a href="#VirusTotalIpReportDialog">VirusTotalIpReportDialog</a></td> +<td>Class implementing a dialog to show the VirusTotal IP address report.</td> +</tr> +</table> +<h3>Functions</h3> +<table> +<tr><td>None</td></tr> +</table> +<hr /><hr /> +<a NAME="VirusTotalIpReportDialog" ID="VirusTotalIpReportDialog"></a> +<h2>VirusTotalIpReportDialog</h2> +<p> + Class implementing a dialog to show the VirusTotal IP address report. +</p> +<h3>Derived from</h3> +QDialog, Ui_VirusTotalIpReportDialog +<h3>Class Attributes</h3> +<table> +<tr><td>None</td></tr> +</table> +<h3>Class Methods</h3> +<table> +<tr><td>None</td></tr> +</table> +<h3>Methods</h3> +<table> +<tr> +<td><a href="#VirusTotalIpReportDialog.__init__">VirusTotalIpReportDialog</a></td> +<td>Constructor</td> +</tr> +</table> +<h3>Static Methods</h3> +<table> +<tr><td>None</td></tr> +</table> +<a NAME="VirusTotalIpReportDialog.__init__" ID="VirusTotalIpReportDialog.__init__"></a> +<h4>VirusTotalIpReportDialog (Constructor)</h4> +<b>VirusTotalIpReportDialog</b>(<i>ip, owner, resolutions, urls, parent=None</i>) +<p> + Constructor +</p><dl> +<dt><i>ip</i> (str)</dt> +<dd> +IP address +</dd><dt><i>owner</i> (str)</dt> +<dd> +owner of the IP address +</dd><dt><i>resolutions</i> (list of dict)</dt> +<dd> +list of resolved host names +</dd><dt><i>urls</i> (list of dict)</dt> +<dd> +list of detected URLs +</dd><dt><i>parent</i> (QWidget)</dt> +<dd> +reference to the parent widget +</dd> +</dl> +<div align="right"><a href="#top">Up</a></div> +<hr /> +</body></html> \ No newline at end of file
--- a/Documentation/Source/index-eric6.Helpviewer.html Sat Jul 25 18:22:34 2015 +0200 +++ b/Documentation/Source/index-eric6.Helpviewer.html Sat Jul 25 20:00:25 2015 +0200 @@ -159,6 +159,12 @@ </tr><tr> <td><a href="eric6.Helpviewer.VirusTotalApi.html">VirusTotalApi</a></td> <td>Module implementing the <a href="http://www.virustotal.com">VirusTotal</a> API class.</td> +</tr><tr> +<td><a href="eric6.Helpviewer.VirusTotalDomainReportDialog.html">VirusTotalDomainReportDialog</a></td> +<td>Module implementing a dialog to show the VirusTotal domain report.</td> +</tr><tr> +<td><a href="eric6.Helpviewer.VirusTotalIpReportDialog.html">VirusTotalIpReportDialog</a></td> +<td>Module implementing a dialog to show the VirusTotal IP address report.</td> </tr> </table> </body></html> \ No newline at end of file
--- a/Helpviewer/HelpWindow.py Sat Jul 25 18:22:34 2015 +0200 +++ b/Helpviewer/HelpWindow.py Sat Jul 25 20:00:25 2015 +0200 @@ -21,7 +21,8 @@ QIcon from PyQt5.QtWidgets import QWidget, QVBoxLayout, QSizePolicy, QDockWidget, \ QComboBox, QLabel, QSplitter, QMenu, QToolButton, QLineEdit, \ - QApplication, QWhatsThis, QDialog, QHBoxLayout, QProgressBar, QAction + QApplication, QWhatsThis, QDialog, QHBoxLayout, QProgressBar, QAction, \ + QInputDialog from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest from PyQt5.QtWebKit import QWebSettings, QWebDatabase, QWebSecurityOrigin from PyQt5.QtWebKitWidgets import QWebPage @@ -1833,70 +1834,23 @@ vttb.setObjectName("VirusTotalToolBar") vttb.setIconSize(UI.Config.ToolBarIconSize) vttb.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) - self.virustotalSearchEdit = QLineEdit() - self.virustotalSearchEdit.setMaximumWidth(250) - self.virustotalSearchEdit.setWhatsThis(self.tr( - """<h2>File search</h2>""" - """<p>In order to search for the last VirusTotal report on a""" - """ given file just enter its hash. Currently the allowed""" - """ hashes are MD5, SHA1 and SHA256. You can also search for""" - """ a particular file report by typing in its permalink id.</p>""" - """<h2>URL search</h2>""" - """<p>URL searches are simple, just type in the given URL, the""" - """ application will normalize it and compare it with the""" - """ entries in VirusTotal's database. Alternatively you may""" - """ enter the MD5 hash of an URL preceded by "url:", e.g.""" - """ url:7f911bbcf618f052ac6b9928600d2820.</p>""" - """<h2>User search</h2>""" - """<p>Do you want to know whether a friend has a VT Community""" - """ account? Simply type in his nick preceded by the symbol""" - """ "@", e.g. @EmilianoMartinez.</p>""" - """<h2>Search through comments</h2>""" - """<p>The comments in VT Community may often help in""" - """ disinfecting your PC or may proof themselves useful when""" - """ analysing a particular malware sample, comment tags enable""" - """ users to search through the VT Community reviews. The""" - """ standard file tags are: {0} The standard URL tags are: {1}""" - """User generated tags are preceded by the symbol "#", e.g.""" - """ #disinfect.</p>""" - ).format( - """<ul>""" - """<li>goodware</li>""" - """<li>malware</li>""" - """<li>spamattachmentorlink</li>""" - """<li>p2pdownload</li>""" - """<li>impropagating</li>""" - """<li>networkworm</li>""" - """<li>drivebydownload</li>""" - """</ul>""", - """<ul>""" - """<li>malicious</li>""" - """<li>benign</li>""" - """<li>malewaredownload</li>""" - """<li>phishingsite</li>""" - """<li>browserexploit</li>""" - """<li>spamlink</li>""" - """</ul>""", - )) - self.virustotalSearchEdit.textChanged.connect( - self.__virusTotalSearchChanged) - self.virustotalSearchEdit.returnPressed.connect( - self.__virusTotalSearch) - vttb.addWidget(self.virustotalSearchEdit) - self.virustotalSearchAct = vttb.addAction( - UI.PixmapCache.getIcon("virustotal.png"), - self.tr("Search VirusTotal"), - self.__virusTotalSearch) - self.virustotalSearchAct.setEnabled(False) - vttb.addSeparator() self.virustotalScanCurrentAct = vttb.addAction( UI.PixmapCache.getIcon("virustotal.png"), self.tr("Scan current site"), self.__virusTotalScanCurrentSite) + self.virustotalIpReportAct = vttb.addAction( + UI.PixmapCache.getIcon("virustotal.png"), + self.tr("IP Address Report"), + self.__virusTotalIpAddressReport) + self.virustotalDomainReportAct = vttb.addAction( + UI.PixmapCache.getIcon("virustotal.png"), + self.tr("Domain Report"), + self.__virusTotalDomainReport) if not Preferences.getHelp("VirusTotalEnabled") or \ Preferences.getHelp("VirusTotalServiceKey") == "": - self.virustotalSearchEdit.setEnabled(False) self.virustotalScanCurrentAct.setEnabled(False) + self.virustotalIpReportAct.setEnabled(False) + self.virustotalDomainReportAct.setEnabled(False) def __nextTab(self): """ @@ -2254,6 +2208,8 @@ self.syncManager().close() + self.__virusTotal.close() + self.searchEdit.openSearchManager().close() if self.useQtHelp: @@ -2514,12 +2470,13 @@ self.__virusTotal.preferencesChanged() if not Preferences.getHelp("VirusTotalEnabled") or \ Preferences.getHelp("VirusTotalServiceKey") == "": - self.virustotalSearchEdit.setEnabled(False) self.virustotalScanCurrentAct.setEnabled(False) + self.virustotalIpReportAct.setEnabled(False) + self.virustotalDomainReportAct.setEnabled(False) else: - self.virustotalSearchEdit.setEnabled(True) self.virustotalScanCurrentAct.setEnabled(True) - self.__virusTotalSearchChanged(self.virustotalSearchEdit.text()) + self.virustotalIpReportAct.setEnabled(True) + self.virustotalDomainReportAct.setEnabled(True) def masterPasswordChanged(self, oldPassword, newPassword): """ @@ -3588,27 +3545,27 @@ ## Interface to VirusTotal below ## ########################################################################### - def __virusTotalSearchChanged(self, txt): - """ - Private slot to react upon changes of the VirusTotal search text. - - @param txt contents of the search (string) - """ - self.virustotalSearchAct.setEnabled( - txt != "" and - Preferences.getHelp("VirusTotalEnabled") and - Preferences.getHelp("VirusTotalServiceKey") != "") - - def __virusTotalSearch(self): - """ - Private slot to search VirusTotal for a given entry. - """ - search = self.virustotalSearchEdit.text() - if search: - from .VirusTotalApi import VirusTotalAPI - requestData = VirusTotalAPI.getSearchRequestData(search) - self.newTab(requestData=requestData) - +## def __virusTotalSearchChanged(self, txt): +## """ +## Private slot to react upon changes of the VirusTotal search text. +## +## @param txt contents of the search (string) +## """ +## self.virustotalSearchAct.setEnabled( +## txt != "" and +## Preferences.getHelp("VirusTotalEnabled") and +## Preferences.getHelp("VirusTotalServiceKey") != "") +## +## def __virusTotalSearch(self): +## """ +## Private slot to search VirusTotal for a given entry. +## """ +## search = self.virustotalSearchEdit.text() +## if search: +## from .VirusTotalApi import VirusTotalAPI +## requestData = VirusTotalAPI.getSearchRequestData(search) +## self.newTab(requestData=requestData) +## def __virusTotalScanCurrentSite(self): """ Private slot to ask VirusTotal for a scan of the URL of the current @@ -3656,6 +3613,41 @@ """ self.newTab(url) + def __virusTotalIpAddressReport(self): + """ + Private slot to retrieve an IP address report. + """ + ip, ok = QInputDialog.getText( + self, + self.tr("IP Address Report"), + self.tr("Enter a valid IPv4 address in dotted quad notation:"), + QLineEdit.Normal) + if ok and ip: + if ip.count(".") == 3: + self.__virusTotal.getIpAddressReport(ip) + else: + E5MessageBox.information( + self, + self.tr("IP Address Report"), + self.tr("""The given IP address is not in dotted quad""" + """ notation.""")) + + def __virusTotalDomainReport(self): + """ + Private slot to retrieve a domain report. + """ + domain, ok = QInputDialog.getText( + self, + self.tr("Domain Report"), + self.tr("Enter a valid domain name:"), + QLineEdit.Normal) + if ok and domain: + self.__virusTotal.getDomainReport(domain) + + ########################################################################### + ## Style sheet handling below ## + ########################################################################### + def reloadUserStyleSheet(self): """ Public method to reload the user style sheet.
--- a/Helpviewer/VirusTotalApi.py Sat Jul 25 18:22:34 2015 +0200 +++ b/Helpviewer/VirusTotalApi.py Sat Jul 25 20:00:25 2015 +0200 @@ -16,9 +16,10 @@ import json -from PyQt5.QtCore import QObject, QUrl, QByteArray, pyqtSignal -from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply, \ - QNetworkAccessManager +from PyQt5.QtCore import QObject, QUrl, QByteArray, pyqtSignal, qVersion +from PyQt5.QtNetwork import QNetworkRequest, QNetworkReply + +from E5Gui import E5MessageBox import Preferences @@ -45,21 +46,21 @@ TestServiceKeyScanID = \ "4feed2c2e352f105f6188efd1d5a558f24aee6971bdf96d5fdb19c197d6d3fad" - ServiceResult_RequestLimitReached = -2 - ServiceResult_InvalidServiceKey = -1 + ServiceResult_ItemQueued = -2 ServiceResult_ItemNotPresent = 0 ServiceResult_ItemPresent = 1 - GetFileReportPattern = "{0}://www.virustotal.com/api/get_file_report.json" - ScanUrlPattern = "{0}://www.virustotal.com/api/scan_url.json" - GetUrlReportPattern = "{0}://www.virustotal.com/api/get_url_report.json" + # HTTP Status Codes + ServiceCode_InvalidKey = 202 + ServiceCode_RateLimitExceeded = 204 + ServiceCode_InvalidPrivilege = 403 - ReportUrlScanPagePattern = \ - "http://www.virustotal.com/url-scan/report.html?id={0}" - ReportFileScanPagePattern = \ - "http://www.virustotal.com/file-scan/report.html?id={0}" - - SearchUrl = "http://www.virustotal.com/search.html" + GetFileReportPattern = "{0}://www.virustotal.com/vtapi/v2/file/report" + ScanUrlPattern = "{0}://www.virustotal.com/vtapi/v2/url/scan" + GetUrlReportPattern = "{0}://www.virustotal.com/vtapi/v2/url/report" + GetIpAddressReportPattern = \ + "{0}://www.virustotal.com/vtapi/v2/ip-address/report" + GetDomainReportPattern = "{0}://www.virustotal.com/vtapi/v2/domain/report" def __init__(self, parent=None): """ @@ -72,6 +73,11 @@ self.__replies = [] self.__loadSettings() + + self.__lastIP = "" + self.__lastDomain = "" + self.__ipReportDlg = None + self.__domainReportDlg = None def __loadSettings(self): """ @@ -84,11 +90,14 @@ self.GetFileReportUrl = self.GetFileReportPattern.format(protocol) self.ScanUrlUrl = self.ScanUrlPattern.format(protocol) self.GetUrlReportUrl = self.GetUrlReportPattern.format(protocol) + self.GetIpAddressReportUrl = self.GetIpAddressReportPattern.format( + protocol) + self.GetDomainReportUrl = self.GetDomainReportPattern.format(protocol) self.errorMessages = { - -2: self.tr("Request limit has been reached."), - -1: self.tr("Invalid key given."), - 0: self.tr("Requested item is not present.") + 204: self.tr("Request limit has been reached."), + 0: self.tr("Requested item is not present."), + -2: self.tr("Requested item is still queued."), } def preferencesChanged(self): @@ -111,7 +120,7 @@ request = QNetworkRequest(QUrl(urlStr)) request.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded") - params = QByteArray("key={0}&resource={1}".format( + params = QByteArray("apikey={0}&resource={1}".format( key, self.TestServiceKeyScanID).encode("utf-8")) import Helpviewer.HelpWindow @@ -129,12 +138,13 @@ reply = self.sender() if reply.error() == QNetworkReply.NoError: - result = json.loads(str(reply.readAll(), "utf-8")) - if result["result"] != self.ServiceResult_InvalidServiceKey: - res = True + res = True + elif reply.error() == self.ServiceCode_InvalidKey: + res = False else: msg = reply.errorString() self.__replies.remove(reply) + reply.deleteLater() self.checkServiceKeyFinished.emit(res, msg) @@ -147,7 +157,7 @@ request = QNetworkRequest(QUrl(self.ScanUrlUrl)) request.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded") - params = QByteArray("key={0}&url=".format( + params = QByteArray("apikey={0}&url=".format( Preferences.getHelp("VirusTotalServiceKey")).encode("utf-8"))\ .append(QUrl.toPercentEncoding(url.toString())) @@ -164,15 +174,54 @@ reply = self.sender() if reply.error() == QNetworkReply.NoError: result = json.loads(str(reply.readAll(), "utf-8")) - if result["result"] == self.ServiceResult_ItemPresent: - self.urlScanReport.emit( - self.ReportUrlScanPagePattern.format(result["scan_id"])) - self.__getFileScanReportUrl(result["scan_id"]) + if result["response_code"] == self.ServiceResult_ItemPresent: + self.urlScanReport.emit(result["permalink"]) + self.__getUrlScanReportUrl(result["scan_id"]) else: - self.submitUrlError.emit(self.errorMessages[result["result"]]) + if result["response_code"] in self.errorMessages: + msg = self.errorMessages[result["response_code"]] + else: + msg = result["verbose_msg"] + self.submitUrlError.emit(msg) + elif reply.error() == self.ServiceCode_RateLimitExceeded: + self.submitUrlError.emit( + self.errorMessages[result[self.ServiceCode_RateLimitExceeded]]) else: self.submitUrlError.emit(reply.errorString()) self.__replies.remove(reply) + reply.deleteLater() + + def __getUrlScanReportUrl(self, scanId): + """ + Private method to get the report URL for a URL scan. + + @param scanId ID of the scan to get the report URL for (string) + """ + request = QNetworkRequest(QUrl(self.GetUrlReportUrl)) + request.setHeader(QNetworkRequest.ContentTypeHeader, + "application/x-www-form-urlencoded") + params = QByteArray("apikey={0}&resource={1}".format( + Preferences.getHelp("VirusTotalServiceKey"), scanId) + .encode("utf-8")) + + import Helpviewer.HelpWindow + nam = Helpviewer.HelpWindow.HelpWindow.networkAccessManager() + reply = nam.post(request, params) + reply.finished.connect(self.__getUrlScanReportUrlFinished) + self.__replies.append(reply) + + def __getUrlScanReportUrlFinished(self): + """ + Private slot to determine the result of the URL scan report URL + request. + """ + reply = self.sender() + if reply.error() == QNetworkReply.NoError: + result = json.loads(str(reply.readAll(), "utf-8")) + if "filescan_id" in result and result["filescan_id"] is not None: + self.__getFileScanReportUrl(result["filescan_id"]) + self.__replies.remove(reply) + reply.deleteLater() def __getFileScanReportUrl(self, scanId): """ @@ -180,10 +229,10 @@ @param scanId ID of the scan to get the report URL for (string) """ - request = QNetworkRequest(QUrl(self.GetUrlReportUrl)) + request = QNetworkRequest(QUrl(self.GetFileReportUrl)) request.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded") - params = QByteArray("key={0}&resource={1}".format( + params = QByteArray("apikey={0}&resource={1}".format( Preferences.getHelp("VirusTotalServiceKey"), scanId) .encode("utf-8")) @@ -201,25 +250,161 @@ reply = self.sender() if reply.error() == QNetworkReply.NoError: result = json.loads(str(reply.readAll(), "utf-8")) - if "file-report" in result: - self.fileScanReport.emit( - self.ReportFileScanPagePattern.format( - result["file-report"])) + self.fileScanReport.emit(result["permalink"]) self.__replies.remove(reply) + reply.deleteLater() - @classmethod - def getSearchRequestData(cls, term): + def getIpAddressReport(self, ipAddress): + """ + Public method to retrieve a report for an IP address. + + @param ipAddress valid IPv4 address in dotted quad notation + @type str + """ + self.__lastIP = ipAddress + + queryItems = [ + ("apikey", Preferences.getHelp("VirusTotalServiceKey")), + ("ip", ipAddress), + ] + url = QUrl(self.GetIpAddressReportUrl) + if qVersion() >= "5.0.0": + from PyQt5.QtCore import QUrlQuery + query = QUrlQuery() + query.setQueryItems(queryItems) + url.setQuery(query) + else: + url.setQueryItems(queryItems) + request = QNetworkRequest(url) + + import Helpviewer.HelpWindow + nam = Helpviewer.HelpWindow.HelpWindow.networkAccessManager() + reply = nam.get(request) + reply.finished.connect(self.__getIpAddressReportFinished) + self.__replies.append(reply) + + def __getIpAddressReportFinished(self): + """ + Private slot to process the IP address report data. """ - Class method to assemble the search request data structure. + reply = self.sender() + if reply.error() == QNetworkReply.NoError: + result = json.loads(str(reply.readAll(), "utf-8")) + if result["response_code"] == 0: + E5MessageBox.information( + None, + self.tr("VirusTotal IP Address Report"), + self.tr("""VirusTotal does not have any information for""" + """ the given IP address.""")) + elif result["response_code"] == -1: + E5MessageBox.information( + None, + self.tr("VirusTotal IP Address Report"), + self.tr("""The submitted IP address is invalid.""")) + else: + owner = result["as_owner"] + resolutions = result["resolutions"] + try: + urls = result["detected_urls"] + except KeyError: + urls = [] + + from .VirusTotalIpReportDialog import VirusTotalIpReportDialog + self.__ipReportDlg = VirusTotalIpReportDialog( + self.__lastIP, owner, resolutions, urls) + self.__ipReportDlg.show() + self.__replies.remove(reply) + reply.deleteLater() + + def getDomainReport(self, domain): + """ + Public method to retrieve a report for a domain. + + @param domain domain name + @type str + """ + self.__lastDomain = domain - @param term search term (string) - @return tuple of network request object, operation and parameters - (QNetworkRequest, QNetworkAccessManager.Operation, QByteArray) + queryItems = [ + ("apikey", Preferences.getHelp("VirusTotalServiceKey")), + ("domain", domain), + ] + url = QUrl(self.GetDomainReportUrl) + if qVersion() >= "5.0.0": + from PyQt5.QtCore import QUrlQuery + query = QUrlQuery() + query.setQueryItems(queryItems) + url.setQuery(query) + else: + url.setQueryItems(queryItems) + request = QNetworkRequest(url) + + import Helpviewer.HelpWindow + nam = Helpviewer.HelpWindow.HelpWindow.networkAccessManager() + reply = nam.get(request) + reply.finished.connect(self.__getDomainReportFinished) + self.__replies.append(reply) + + def __getDomainReportFinished(self): + """ + Private slot to process the IP address report data. """ - request = QNetworkRequest(QUrl(cls.SearchUrl)) - request.setHeader(QNetworkRequest.ContentTypeHeader, - "application/x-www-form-urlencoded") - op = QNetworkAccessManager.PostOperation - params = QByteArray(b"chain=").append(QUrl.toPercentEncoding(term)) + reply = self.sender() + if reply.error() == QNetworkReply.NoError: + result = json.loads(str(reply.readAll(), "utf-8")) + if result["response_code"] == 0: + E5MessageBox.information( + None, + self.tr("VirusTotal Domain Report"), + self.tr("""VirusTotal does not have any information for""" + """ the given domain.""")) + elif result["response_code"] == -1: + E5MessageBox.information( + None, + self.tr("VirusTotal Domain Report"), + self.tr("""The submitted domain address is invalid.""")) + else: + resolutions = result["resolutions"] + try: + urls = result["detected_urls"] + except KeyError: + urls = [] + try: + subdomains = result["subdomains"] + except KeyError: + subdomains = [] + try: + bdCategory = result["BitDefender category"] + except KeyError: + bdCategory = self.tr("not available") + try: + tmCategory = result["TrendMicro category"] + except KeyError: + tmCategory = self.tr("not available") + try: + wtsCategory = result["Websense ThreatSeeker category"] + except KeyError: + wtsCategory = self.tr("not available") + try: + categories = result["categories"] + except KeyError: + categories = [] + + from .VirusTotalDomainReportDialog import \ + VirusTotalDomainReportDialog + self.__domainReportDlg = VirusTotalDomainReportDialog( + self.__lastDomain, resolutions, urls, subdomains, + bdCategory, tmCategory, wtsCategory, categories) + self.__domainReportDlg.show() + self.__replies.remove(reply) + reply.deleteLater() + + def close(self): + """ + Public slot to close the API. + """ + for reply in self.__replies: + reply.abort() - return (request, op, params) + self.__ipReportDlg and self.__ipReportDlg.close() + self.__domainReportDlg and self.__domainReportDlg.close()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Helpviewer/VirusTotalDomainReportDialog.py Sat Jul 25 20:00:25 2015 +0200 @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2015 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to show the VirusTotal domain report. +""" + +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QDialog, QTreeWidgetItem + +from .Ui_VirusTotalDomainReportDialog import Ui_VirusTotalDomainReportDialog + + +class VirusTotalDomainReportDialog(QDialog, Ui_VirusTotalDomainReportDialog): + """ + Class implementing a dialog to show the VirusTotal domain report. + """ + def __init__(self, domain, resolutions, urls, subdomains, + bdCategory, tmCategory, wtsCategory, categories, parent=None): + """ + Constructor + + @param domain domain name + @type str + @param resolutions list of resolved host names + @type list of dict + @param urls list of detected URLs + @type list of dict + @param subdomains list of subdomains + @type list of str + @param bdCategory BitDefender categorization + @type str + @param tmCategory TrendMicro categorization + @type str + @param wtsCategory Websense ThreatSeeker categorization + @type str + @param categories list of categorizations + @type list of str + @param parent reference to the parent widget + @type QWidget + """ + super(VirusTotalDomainReportDialog, self).__init__(parent) + self.setupUi(self) + self.setWindowFlags(Qt.Window) + + self.headerLabel.setText( + self.tr("<b>Report for domain {0}</b>").format(domain)) + + for resolution in resolutions: + QTreeWidgetItem( + self.resolutionsList, + [resolution["ip_address"], + resolution["last_resolved"].split()[0]] + ) + self.resolutionsList.resizeColumnToContents(0) + self.resolutionsList.resizeColumnToContents(1) + self.resolutionsList.sortByColumn(0, Qt.AscendingOrder) + + if not urls: + self.detectedUrlsGroup.setVisible(False) + for url in urls: + QTreeWidgetItem( + self.urlsList, + [url["url"], + self.tr("{0}/{1}", "positives / total").format( + url["positives"], url["total"]), + url["scan_date"].split()[0]] + ) + self.urlsList.resizeColumnToContents(0) + self.urlsList.resizeColumnToContents(1) + self.urlsList.resizeColumnToContents(2) + self.urlsList.sortByColumn(0, Qt.AscendingOrder) + + if not subdomains: + self.subdomainsGroup.setVisible(False) + else: + self.subdomainsList.addItems(subdomains) + self.subdomainsList.sortItems() + + self.bdLabel.setText(bdCategory) + self.tmLabel.setText(tmCategory) + self.wtsLabel.setText(wtsCategory) +## +## if not categories: +## self.categoriesList.setVisible(False) +## else: +## self.categoriesList.addItems(categories) +## self.categoriesList.sortItems()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Helpviewer/VirusTotalDomainReportDialog.ui Sat Jul 25 20:00:25 2015 +0200 @@ -0,0 +1,278 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>VirusTotalDomainReportDialog</class> + <widget class="QDialog" name="VirusTotalDomainReportDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>900</width> + <height>700</height> + </rect> + </property> + <property name="windowTitle"> + <string>Domain Report</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <widget class="QLabel" name="headerLabel"/> + </item> + <item> + <widget class="Line" name="line9_3"> + <property name="frameShape"> + <enum>QFrame::HLine</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Categorizations</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string notr="true">BitDefender:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="bdLabel"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string notr="true">TrendMicro:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="tmLabel"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string notr="true">Websense ThreatSeeker:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="wtsLabel"> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>690</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QGroupBox" name="resolutionsGroup"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>4</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Resolutions</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QTreeWidget" name="resolutionsList"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string>IP-Address</string> + </property> + </column> + <column> + <property name="text"> + <string>Resolved Date</string> + </property> + </column> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="subdomainsGroup"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>4</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Subdomains</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QListWidget" name="subdomainsList"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QGroupBox" name="detectedUrlsGroup"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>2</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Detected URLs</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QTreeWidget" name="urlsList"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string>URL</string> + </property> + </column> + <column> + <property name="text"> + <string>Scan Result</string> + </property> + </column> + <column> + <property name="text"> + <string>Scan Date</string> + </property> + </column> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Close</set> + </property> + </widget> + </item> + </layout> + </widget> + <tabstops> + <tabstop>resolutionsList</tabstop> + <tabstop>subdomainsList</tabstop> + <tabstop>urlsList</tabstop> + </tabstops> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>VirusTotalDomainReportDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>VirusTotalDomainReportDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Helpviewer/VirusTotalIpReportDialog.py Sat Jul 25 20:00:25 2015 +0200 @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2015 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to show the VirusTotal IP address report. +""" + +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QDialog, QTreeWidgetItem + +from .Ui_VirusTotalIpReportDialog import Ui_VirusTotalIpReportDialog + + +class VirusTotalIpReportDialog(QDialog, Ui_VirusTotalIpReportDialog): + """ + Class implementing a dialog to show the VirusTotal IP address report. + """ + def __init__(self, ip, owner, resolutions, urls, parent=None): + """ + Constructor + + @param ip IP address + @type str + @param owner owner of the IP address + @type str + @param resolutions list of resolved host names + @type list of dict + @param urls list of detected URLs + @type list of dict + @param parent reference to the parent widget + @type QWidget + """ + super(VirusTotalIpReportDialog, self).__init__(parent) + self.setupUi(self) + self.setWindowFlags(Qt.Window) + + self.headerLabel.setText( + self.tr("<b>Report for IP {0}</b>").format(ip)) + self.ownerLabel.setText(owner) + + for resolution in resolutions: + QTreeWidgetItem( + self.resolutionsList, + [resolution["hostname"], + resolution["last_resolved"].split()[0]] + ) + self.resolutionsList.resizeColumnToContents(0) + self.resolutionsList.resizeColumnToContents(1) + self.resolutionsList.sortByColumn(0, Qt.AscendingOrder) + + if not urls: + self.detectedUrlsGroup.setVisible(False) + for url in urls: + QTreeWidgetItem( + self.urlsList, + [url["url"], + self.tr("{0}/{1}", "positives / total").format( + url["positives"], url["total"]), + url["scan_date"].split()[0]] + ) + self.urlsList.resizeColumnToContents(0) + self.urlsList.resizeColumnToContents(1) + self.urlsList.resizeColumnToContents(2) + self.urlsList.sortByColumn(0, Qt.AscendingOrder)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Helpviewer/VirusTotalIpReportDialog.ui Sat Jul 25 20:00:25 2015 +0200 @@ -0,0 +1,194 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>VirusTotalIpReportDialog</class> + <widget class="QDialog" name="VirusTotalIpReportDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>600</height> + </rect> + </property> + <property name="windowTitle"> + <string>IP Address Report</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="headerLabel"/> + </item> + <item> + <widget class="Line" name="line9_3"> + <property name="frameShape"> + <enum>QFrame::HLine</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Owner:</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="ownerLabel"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QGroupBox" name="resolutionsGroup"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>4</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Resolutions</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QTreeWidget" name="resolutionsList"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string>Hostname</string> + </property> + </column> + <column> + <property name="text"> + <string>Resolved Date</string> + </property> + </column> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="detectedUrlsGroup"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>2</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Detected URLs</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QTreeWidget" name="urlsList"> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string>URL</string> + </property> + </column> + <column> + <property name="text"> + <string>Scan Result</string> + </property> + </column> + <column> + <property name="text"> + <string>Scan Date</string> + </property> + </column> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Close</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>VirusTotalIpReportDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>VirusTotalIpReportDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui>
--- a/Preferences/__init__.py Sat Jul 25 18:22:34 2015 +0200 +++ b/Preferences/__init__.py Sat Jul 25 20:00:25 2015 +0200 @@ -843,7 +843,7 @@ "AccessKeysEnabled": True, "VirusTotalEnabled": False, "VirusTotalServiceKey": "", - "VirusTotalSecure": False, + "VirusTotalSecure": True, "SearchLanguage": QLocale().language(), "DoNotTrack": False, "SendReferer": True,
--- a/eric6.e4p Sat Jul 25 18:22:34 2015 +0200 +++ b/eric6.e4p Sat Jul 25 20:00:25 2015 +0200 @@ -426,6 +426,8 @@ <Source>Helpviewer/UserAgent/UserAgentsDialog.py</Source> <Source>Helpviewer/UserAgent/__init__.py</Source> <Source>Helpviewer/VirusTotalApi.py</Source> + <Source>Helpviewer/VirusTotalDomainReportDialog.py</Source> + <Source>Helpviewer/VirusTotalIpReportDialog.py</Source> <Source>Helpviewer/WebPlugins/ClickToFlash/ClickToFlash.py</Source> <Source>Helpviewer/WebPlugins/ClickToFlash/ClickToFlashPlugin.py</Source> <Source>Helpviewer/WebPlugins/ClickToFlash/ClickToFlashWhitelistDialog.py</Source> @@ -1322,6 +1324,8 @@ <Form>Helpviewer/UrlBar/BookmarkActionSelectionDialog.ui</Form> <Form>Helpviewer/UrlBar/BookmarkInfoDialog.ui</Form> <Form>Helpviewer/UserAgent/UserAgentsDialog.ui</Form> + <Form>Helpviewer/VirusTotalDomainReportDialog.ui</Form> + <Form>Helpviewer/VirusTotalIpReportDialog.ui</Form> <Form>Helpviewer/WebPlugins/ClickToFlash/ClickToFlash.ui</Form> <Form>Helpviewer/WebPlugins/ClickToFlash/ClickToFlashWhitelistDialog.ui</Form> <Form>IconEditor/IconSizeDialog.ui</Form>