[Inteproxy-commits] r60 - in trunk: . inteproxy

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Mon Apr 23 16:54:50 CEST 2007


Author: bh
Date: 2007-04-23 16:54:50 +0200 (Mon, 23 Apr 2007)
New Revision: 60

Added:
   trunk/inteproxy/feesdialog.py
Modified:
   trunk/ChangeLog
   trunk/InteProxy.py
Log:
* inteproxy/feesdialog.py: New.  Dialog for fees and access
constraints and code to extract the information from a
GetCapabilities response.

* InteProxy.py (InteProxyHTTPRequestHandler.handle_proxy_request):
Show the feesdialog when appropriate


Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2007-04-23 12:54:25 UTC (rev 59)
+++ trunk/ChangeLog	2007-04-23 14:54:50 UTC (rev 60)
@@ -1,5 +1,14 @@
 2007-04-23  Bernhard Herzog  <bh at intevation.de>
 
+	* inteproxy/feesdialog.py: New.  Dialog for fees and access
+	constraints and code to extract the information from a
+	GetCapabilities response.
+
+	* InteProxy.py (InteProxyHTTPRequestHandler.handle_proxy_request):
+	Show the feesdialog when appropriate
+
+2007-04-23  Bernhard Herzog  <bh at intevation.de>
+
 	* inteproxy, inteproxy/__init__.py: New.  Introduce inteproxy
 	package for better code organisation
 

Modified: trunk/InteProxy.py
===================================================================
--- trunk/InteProxy.py	2007-04-23 12:54:25 UTC (rev 59)
+++ trunk/InteProxy.py	2007-04-23 14:54:50 UTC (rev 60)
@@ -26,6 +26,7 @@
 from inteproxy.transcoder import transcoder_map
 from inteproxy.getpassword import getpassword
 from inteproxy.threadpool import ThreadPool
+from inteproxy.feesdialog import handle_fees_and_access_constraints
 
 inteproxy_version = "0.1.2"
 
@@ -158,6 +159,9 @@
         self.log_debug("received response: %s: %r", response.code,
                        response.msg)
 
+        # check for fees and access constraints and run a dialog
+        response_read = handle_fees_and_access_constraints(remote_url, response)
+
         # Ideally, the HTTP version in our reply to the client should be
         # what the remote server used in its reply.  Unfortunately,
         # there doesn't seem to be a way to get that information from
@@ -182,7 +186,7 @@
         self.end_headers()
 
         transfer_encoding = response.info().get("Transfer-encoding")
-        self.transfer_data(response.read, self.wfile.write,
+        self.transfer_data(response_read, self.wfile.write,
                            chunked = (transfer_encoding == "chunked"))
         self.log_debug("request finished")
 

Added: trunk/inteproxy/feesdialog.py
===================================================================
--- trunk/inteproxy/feesdialog.py	2007-04-23 12:54:25 UTC (rev 59)
+++ trunk/inteproxy/feesdialog.py	2007-04-23 14:54:50 UTC (rev 60)
@@ -0,0 +1,145 @@
+# Copyright (C) 2007 by Intevation GmbH
+# Authors:
+# Bernhard Herzog <bh at intevation.de>
+#
+# This program is free software under the GPL (>=v2)
+# Read the file COPYING coming with the software for details.
+
+"""GetCapabilities Fees/AccessConstraints processing"""
+
+import urlparse
+from StringIO import StringIO
+
+from lxml import etree
+
+try:
+    import gtk
+except ImportError:
+    gtk = None
+
+
+def run_fees_dialog(title, fees, access_constraints):
+    """Shows fees and access_constraints information in a dialog
+
+    The title, fees and access_constraints should be strings taken from
+    the corresponding sub-elements of the Service element of the
+    GetCapabilities response.  Both fees and access_constraints is false
+    (e.g. both are empty strings or None), the dialog is not shown and
+    this function does nothing.  Also, if gtk is not available, the
+    function does nothing.
+    """
+    if gtk is None:
+        return
+
+    if not fees and not access_constraints:
+        return
+
+    dialog = gtk.Dialog("Fees and AccessConstraints", None,
+                        gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
+                        (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
+
+    label_texts = ["Service information for %s" % title]
+
+    if fees:
+        label_texts.extend([("<b>Fees:</b>", True),
+                            fees])
+    if access_constraints:
+        label_texts.extend([("<b>Access Constraints:</b>", True),
+                            access_constraints])
+    for item in label_texts:
+        if isinstance(item, tuple):
+            text, markup = item
+        else:
+            text = item
+            markup = False
+        label = gtk.Label(text)
+        label.set_use_markup(markup)
+        label.set_alignment(0.0, 0.5)
+        label.set_padding(5, 5)
+        label.show()
+        dialog.vbox.pack_start(label, True, True, 5)
+
+    dialog.run()
+    dialog.destroy()
+
+    # process pending events to make sure the dialog is destroyed and
+    # unmapped properly from the screen.
+    while gtk.events_pending():
+        gtk.main_iteration_do()
+
+
+
+# keep track of the URLs for which the dialog was already shown.
+dialog_shown_for = dict()
+
+
+def is_get_capabilities_url(url):
+    scheme, netloc, path, query, fragment = urlparse.urlsplit(url)
+
+    if query:
+        split_query = query.split("&")
+        if "REQUEST=GetCapabilities" in split_query:
+            return True
+
+    return False
+
+
+def parse_capabilities(xml):
+    """Parses the capabilities information and returns some of the information
+
+    The return value is a tuple (title, fees, access_constraints) with
+    the contents of the correspondings sub-elements of the xml
+    structures Service element"""
+    t = etree.parse(StringIO(xml))
+    title = t.findtext("Service/Title")
+    if not title:
+        # according to the DTD the Title must always be present,
+        # but who known what real servers do.  If the title is
+        # not present, we use the URL instead
+        title = remote_url
+    fees = t.findtext("Service/Fees")
+    access_constraints = t.findtext("Service/AccessConstraints")
+    return (title, fees, access_constraints)
+
+
+
+def handle_fees_and_access_constraints(remote_url, response):
+    """Runs Fees/AccessConstraints dialog for GetCapabilities responses
+
+    This function uses is_get_capabilities_url to determine whether the
+    remote_url was a GetCapabilities request.  If that is the case, the
+    response is assumed to be a GetCapabilities response.  This function
+    then parses the response as XML and extract Fees and
+    AccessConstraints information from it and shows them in a dialog.
+
+    The response parameter should be the urllib2 response object for the
+    remote url.  This function has to read the entire response in order
+    to parse it.  A side effect of this is that the response's read
+    method can no longer be used by the caller to read the response.
+    Therefore this function always returns a callable object that
+    behaves like the original response's read method that can be used
+    instead.
+
+    The function keeps track of which URLs were already processed, so
+    that the dialog is never shown twice for the same URL.
+    """
+    response_read = response.read
+
+    if remote_url in dialog_shown_for:
+        return response_read
+
+    if is_get_capabilities_url(remote_url):
+        title, fees, access_constraints = parse_capabilities(response_read())
+        run_fees_dialog(title, fees, access_constraints)
+
+        dialog_shown_for[remote_url] = True
+
+        response_read = StringIO(data).read
+
+    return response_read
+
+
+# Manual tests when running this module as a script
+if __name__ == "__main__":
+    run_fees_dialog("Demo WMS Server", "Sample Fees Text",
+                    "Sample AccessConstraints text")


Property changes on: trunk/inteproxy/feesdialog.py
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + native



More information about the Inteproxy-commits mailing list