Esempio n. 1
0
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)
Esempio n. 2
0
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