class NetManager(object): def __init__(self, callback): self._network_manager = QNetworkAccessManager() # connect signals self._network_manager.sslErrors.connect(self._ssl_errors) self._network_manager.finished.connect(self._finished) # bind a custom virtual function to createRequest self._network_manager.createRequest = self._create_request # a dict of available request methods self._request_methods = { 'delete': lambda r, d: self._network_manager.deleteResource(r), 'get': lambda r, d: self._network_manager.get(r), 'head': lambda r, d: self._network_manager.head(r), 'post': lambda r, d: self._network_manager.post(r, d), 'put': lambda r, d: self._network_manager.put(r, d), } # store the callback function which will be called when a request is # finished self._result_callback = callback def _ssl_errors(self, reply, errors): # currently we ignore all ssl related errors reply.ignoreSslErrors() def _finished(self, reply): # Called when a request is finished, whether it was successful or not. # Obtain some basic information about the request reply_url = reply.url().toString() # Request headers request_headers = dict((str(hdr), str(reply.request().rawHeader(hdr))) for hdr in reply.request().rawHeaderList()) # Reply headers reply_headers = dict((str(hdr), str(reply.rawHeader(hdr))) for hdr in reply.rawHeaderList()) status_code = reply.attribute(QNetworkRequest.HttpStatusCodeAttribute) reason = reply.attribute(QNetworkRequest.HttpReasonPhraseAttribute) redirect = reply.attribute(QNetworkRequest.RedirectionTargetAttribute) result = {'reply_url': smart_str(reply_url), 'status_code': status_code, 'reason': reason, 'redirect_to': smart_str(redirect.toString()), 'request_headers': request_headers, 'reply_headers': reply_headers} if reply.error() == QNetworkReply.NoError: # request was successful result['successful'] = True result['reply_data'] = reply.readAll() else: # request was not successful result['successful'] = False result['error'] = reply.error() result['error_msg'] = reply.errorString() # schedule the reply object for deletion reply.deleteLater() # calling the callback function which we passed upon instantiation to # report the results there self._result_callback(result) def _create_request(self, operation, request, data): try: raw_data = smart_str(data.peek(8192)) except AttributeError: # data is None, nothing will be sent in this request pass else: parsed_data = '\n'.join(raw_data.split('&')) print parsed_data reply = QNetworkAccessManager.createRequest(self._network_manager, operation, request, data) return reply def _prepare_request(self, url, headers): # create an empty request request = QNetworkRequest() # assign a url to it request.setUrl(QUrl(url)) # add some custom headers to the request for (header_name, header_value) in headers.items(): request.setRawHeader(header_name, QByteArray(header_value)) return request def _urlencode_request_data(self, raw_data): # the data which we want to send to the server must be urlencoded request_data = QUrl() for (name, value) in raw_data.items(): request_data.addQueryItem(name, unicode(value)) return request_data.encodedQuery() def perform(self, method, url, headers, raw_data=None): # create the request object request = self._prepare_request(url, headers) # urlencode the request data request_data = self._urlencode_request_data(raw_data or dict()) # locate the request function for the choosen request method request_func = self._request_methods[method.lower()] # initiate request request_func(request, request_data)
class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setupUi(self) self.invoice_form = InvoiceForm(self) self.action_Account.triggered.connect(self.show_account_editor) self.action_Update.triggered.connect(self.update_usage) self.action_About.triggered.connect(self.about) self.actionInvoice.triggered.connect(self.invoice_form.show) self.network_access_manager = QNetworkAccessManager() self.network_access_manager.finished.connect(self.fetched_usages) self.network_access_manager.sslErrors.connect(self.allow_connection) self.settings = QSettings('Nasim', 'BLUsage') self.file_name = os.path.expanduser('~/.BLUsage.dat') self.usage_model = BLUsage() self.read_usage() self.tree_model = TreeModel(self.usage_model.usage) self.treeView.setModel(self.tree_model) self.treeView.resizeColumnToContents(0) if not self.usage_model.username: self.show_account_editor() self.treeView.header().setResizeMode(QHeaderView.Stretch) self.treeView.header().setResizeMode(0, QHeaderView.ResizeToContents) self.treeView.setAlternatingRowColors(True) self.accountName.setText(self.usage_model.name) self.progressBar.setHidden(True) self.show_lastupdate() def show_account_editor(self): AccountDialog(self.usage_model, self).exec_() self.accountName.setText(self.usage_model.name) self.show_lastupdate() self.write_usage() def about(self): QMessageBox.about(self, "BLUsage", """Bangla Lion bandwidth usage viewer. Version 2.0 Author: M. Nasimul Haque email: [email protected] Web: http://www.nasim.me.uk""") def update_usage(self): if not all([self.usage_model.username, self.usage_model.password]): QMessageBox.critical(self, 'No account', 'Please enter your account details first.') return request = QNetworkRequest(QUrl(self.usage_model.user_endpoint)) self.network_access_manager.post(request, self.usage_model.post_data) self.updateButton.setEnabled(False) self.progressBar.setHidden(False) self.progressBar.setValue(0) self.statusBar.showMessage("Please wait...") def fetched_usages(self, reply): self.updateButton.setEnabled(True) self.progressBar.setHidden(True) if reply.error() == QNetworkReply.NoError: if not self.usage_model.parse(str(reply.readAll())): title = "Parsing error" message = self.usage_model.error else: title = None self.tree_model.deleteLater() self.tree_model = TreeModel(self.usage_model.usage) self.treeView.setModel(self.tree_model) self.show_lastupdate() self.write_usage() elif reply.error() in [QNetworkReply.AuthenticationRequiredError, QNetworkReply.ContentAccessDenied]: title = "Authentication error" message = "Please check your account credentials." else: title = "An error occured" message = reply.errorString() \ + ".\nPlease check your internet connection." if title: QMessageBox.critical(self, title, message) reply.deleteLater() def allow_connection(self, reply): reply.ignoreSslErrors() def read_usage(self): self.usage_model.name = self.settings.value('name') self.usage_model.username = self.settings.value('username') self.usage_model.password = self.settings.value('password') self.usage_model.last_update = self.settings.value('last_update') self.usage_model.capKB = int(self.settings.value('cap') or 0) self.usage_model.totalKB = int(self.settings.value('total') or 0) start = self.settings.value('start') if not start: today = QDate.currentDate() start = QDate(today.year(), today.month(), 1) self.usage_model.start = start end = self.settings.value('end') if not end: end = start.addDays(29) self.usage_model.end = end def write_usage(self): self.settings.setValue('name', self.usage_model.name) self.settings.setValue('username', self.usage_model.username) self.settings.setValue('password', self.usage_model.password) self.settings.setValue('start', self.usage_model.start) self.settings.setValue('end', self.usage_model.end) self.settings.setValue('last_update', self.usage_model.last_update) self.settings.setValue('cap', self.usage_model.capKB) self.settings.setValue('total', self.usage_model.totalKB) def show_lastupdate(self): self.totalLabel.setText("Totals usage: <b>%s</b>" % (self.usage_model.smart_bytes(self.usage_model.totalKB),)) remaining = self.usage_model.remaining() if isinstance(remaining, int): self.remainingLabel.setText("Remaining: <b>%s</b>" % (self.usage_model.smart_bytes(remaining),)) else: self.remainingLabel.setText("Remaining: <b>Unlimited</b>") try: if not self.usage_model.last_update: self.statusBar.showMessage("Ready") else: self.statusBar.showMessage("Last updated on: " + self.usage_model.last_update.toString()) except: pass