From 34be90f247b7a5f52b31aaf4a1487426290ff1e7 Mon Sep 17 00:00:00 2001 From: Jon Dunleavy Date: Fri, 13 Apr 2012 13:15:52 +0100 Subject: [PATCH] urls can now have keyword params parsed out i.e. /contact/1 --- framework/handlers/__init__.py | 1 + framework/handlers/qnetworkhandler.py | 48 ++++++++++++++++++++++ framework/networkaccessmanager.py | 57 +++++---------------------- urls.py | 5 ++- 4 files changed, 61 insertions(+), 50 deletions(-) create mode 100644 framework/handlers/__init__.py create mode 100644 framework/handlers/qnetworkhandler.py diff --git a/framework/handlers/__init__.py b/framework/handlers/__init__.py new file mode 100644 index 0000000..32a0de1 --- /dev/null +++ b/framework/handlers/__init__.py @@ -0,0 +1 @@ +__author__ = 'jond' diff --git a/framework/handlers/qnetworkhandler.py b/framework/handlers/qnetworkhandler.py new file mode 100644 index 0000000..1386127 --- /dev/null +++ b/framework/handlers/qnetworkhandler.py @@ -0,0 +1,48 @@ +__author__ = 'jond' + +from PySide import QtCore, QtNetwork + +class FakeReply(QtNetwork.QNetworkReply): + """ + The reply class that is used when a url is to be dealt with by the application + and is not to be dealt with by the usual method + """ + def __init__(self, parent, request, operation, f, args={}): + """ + @type args: dict + """ + QtNetwork.QNetworkReply.__init__(self, parent) + self.setRequest(request) + self.setUrl(request.url()) + self.setOperation(operation) + self.open(self.ReadOnly | self.Unbuffered) + # if any are lists of 1 item then just send the item through + for k, v in args.items(): + if type(v) is type([]): + if len(v) is 1: + args[k] = v[0] + self.content = f(**args) + self.offset = 0 + + self.setHeader(QtNetwork.QNetworkRequest.ContentTypeHeader, "application/json; charset=UTF-8") + self.setHeader(QtNetwork.QNetworkRequest.ContentLengthHeader, len(self.content)) + + QtCore.QTimer.singleShot(0, self, QtCore.SIGNAL("readyRead()")) + QtCore.QTimer.singleShot(0, self, QtCore.SIGNAL("finished()")) + + + def abort(self): + pass + + def bytesAvailable(self): + return len(self.content) - self.offset + + def isSequential(self): + return True + + def readData(self, maxSize): + if self.offset < len(self.content): + end = min(self.offset + maxSize, len(self.content)) + data = self.content[self.offset:end] + self.offset = end + return data diff --git a/framework/networkaccessmanager.py b/framework/networkaccessmanager.py index 4fd0002..2a20f51 100644 --- a/framework/networkaccessmanager.py +++ b/framework/networkaccessmanager.py @@ -2,9 +2,9 @@ __author__ = 'jond' import re -import json import urlparse import urllib +import framework.handlers.qnetworkhandler as qnetworkhandler try: from PyQt4 import QtCore, QtNetwork @@ -19,75 +19,36 @@ class NetworkAccessManager(QtNetwork.QNetworkAccessManager): """ - Our network asccess manager that is used instead of the default - This allows us to jump in and interupt the calls to usually external + Our network access manager that is used instead of the default + This allows us to jump in and interrupt the calls to usually external services """ def createRequest(self, operation, request, data): """ Deal with the request when it comes in + TODO: Only deals with keyworded get requests in urls not ordered """ reply = None requrl = request.url() requrlstr = requrl.toString() for urltuple in urls.REDIRECTS: - if re.search(urltuple[0], requrlstr): + m = re.search(urltuple[0], requrlstr) + if m: argd = {} if data is not None: # parse the post data postargs = unicode(data.readAll()) argd = urlparse.parse_qs(urllib.unquote_plus(postargs.encode('ascii')).decode('utf-8'), keep_blank_values=True) + # add get data keyword arguments + argd.update(m.groupdict()) - reply = FakeReply(self, request, operation, urltuple[1], argd) + reply = qnetworkhandler.FakeReply(self, request, operation, urltuple[1], argd) # set up the reply with the correct status reply.setAttribute(QtNetwork.QNetworkRequest.HttpStatusCodeAttribute, 200) if reply is None: reply = QtNetwork.QNetworkAccessManager.createRequest(self, operation, request, data) return reply -class FakeReply(QtNetwork.QNetworkReply): - """ - The reply class that is used when a url is to be dealt with by the application - and is not to be dealt with by the usual method - """ - def __init__(self, parent, request, operation, f, args={}): - """ - @type args: dict - """ - QtNetwork.QNetworkReply.__init__(self, parent) - self.setRequest(request) - self.setUrl(request.url()) - self.setOperation(operation) - self.open(self.ReadOnly | self.Unbuffered) - # if any are lists of 1 item then just send the item through - for k, v in args.items(): - if type(v) is type([]): - if len(v) is 1: - args[k] = v[0] - self.content = f(**args) - self.offset = 0 - - self.setHeader(QtNetwork.QNetworkRequest.ContentTypeHeader, "application/json; charset=UTF-8") - self.setHeader(QtNetwork.QNetworkRequest.ContentLengthHeader, len(self.content)) - - QtCore.QTimer.singleShot(0, self, QtCore.SIGNAL("readyRead()")) - QtCore.QTimer.singleShot(0, self, QtCore.SIGNAL("finished()")) - - - def abort(self): - pass - - def bytesAvailable(self): - return len(self.content) - self.offset - - def isSequential(self): - return True - def readData(self, maxSize): - if self.offset < len(self.content): - end = min(self.offset + maxSize, len(self.content)) - data = self.content[self.offset:end] - self.offset = end - return data diff --git a/urls.py b/urls.py index 22a4c31..4aecf7b 100644 --- a/urls.py +++ b/urls.py @@ -3,5 +3,6 @@ import re import views -REDIRECTS = ((re.compile('contacts'), views.getcontacts), - (re.compile('contact/add.json'), views.addcontact)) \ No newline at end of file +REDIRECTS = ((re.compile(r'contacts'), views.getcontacts), + (re.compile(r'contact/(?P[\d]+)'), views.getcontacts), + (re.compile('contact/add'), views.addcontact)) \ No newline at end of file