[GRASS-SVN] r47470 - grass-addons/grass7/gui/wxpython/wx.wms

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Aug 6 15:37:29 EDT 2011


Author: sudeepsingh
Date: 2011-08-06 12:37:29 -0700 (Sat, 06 Aug 2011)
New Revision: 47470

Added:
   grass-addons/grass7/gui/wxpython/wx.wms/savepopup.py
Modified:
   grass-addons/grass7/gui/wxpython/wx.wms/TODO
   grass-addons/grass7/gui/wxpython/wx.wms/addserver.py
   grass-addons/grass7/gui/wxpython/wx.wms/parse.py
   grass-addons/grass7/gui/wxpython/wx.wms/wmsmenu.py
Log:
some bugs fixed, details in TODO file

Modified: grass-addons/grass7/gui/wxpython/wx.wms/TODO
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.wms/TODO	2011-08-06 16:03:47 UTC (rev 47469)
+++ grass-addons/grass7/gui/wxpython/wx.wms/TODO	2011-08-06 19:37:29 UTC (rev 47470)
@@ -1,4 +1,4 @@
-Here is a list of known issues with wms layer implementation. These bugs are known and are to be fixed soon. 
+Here is a list of known issues with wms layer implementation. These bugs are known and are to be fixed soon. Please feel free to report an bugs you find in this version by email at sudeep495 at gmail.com . This version is under development so, quite a number of bugs are expected. More these are reported, better it is. 
 
 1.Right Indented User Names 
 ڝڍڑڭڏڧڲڝڍڑڭڏڧڲ
@@ -15,6 +15,12 @@
 6.In case, on adding or removing a server, if the write to file is unsuccessful, the application removes it from the serverlist, even though is not written in the file.
 So when the application restarts, all the changes done are lost, since data was not written to file successfuly. 
 
+7.Name of temporary file to be changed to ServersList.xml~ from tempList.xml
+
+8.The Save/Dont Save/Cancel popup works fine for the first time, but for the 2nd time leads to PyDeadObjectError error. This bug is known and is of serious nature. Fix to be done soon. 
+Some other issues detected with this popup. Like when adding a new server name "</servername>" , and then click on save and then on quit, the popup appears, now click on cancel. After clicking on cancel, another popup appears and this continues. Serious issue. This popups code needs to be checked throughly. 
+
+
 More to be added...
 
 
@@ -26,3 +32,103 @@
 1.[Fixed]Username checked for delimeter presence
 2.[Fixed]On closing add server window, main window also closes.
 3.[Fixed]In addserver.py when pressing the quit button or closing it, main wmsmenu window closes, and it gives an error of maximum recurssion depth reached error. 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Following are issues reported by Maris and their current status. (Issues marked with [done] are fixed). 
+
+
+Issues reportes by Maris , Mail 1
+
+
+AddServer dialog:
+* TODO: Dialog layout doesn't re-size well; Text doesn't fit.
+*[done] Quit button quits application and not just closes server editing dialog.
+* Save button should save edits to current server and not create a new
+one; "Save as a new" should create a new entry.
+* TODO: check for name duplication before adding a new server to avoid
+existence of server entries with identical names. That would break
+current XML too, as common name is used as ID. ID should be something
+more generic. UUID?
+*[done]  Only server name and URL should be mandatory
+* TODO: StatusBar should provide real info on application state:
+editing existing entry; creating a new one; saved successfully; save
+failed + popup with error message etc.
+* If a new server is saved successfully, preselect it in servers drop-down list.
+*[done]  Failure to save server list should not wipe existing server list.
+This is important! Use copy on success trick (save to temporary file;
+in case of success, copy temporary file over original one).
+*[done]  All fields should accept non-ascii characters.
+* TODO: validate user provided URL by doing getCapabilities request.
+* When server is removed, it should switch dropdown server list to
+other entry to indicate it's removal.
+
+wmsmenu:
+*[done]  Code makes assumptions that serverlist files are readable and
+writable. This might not be true. Just chmod -r serverlist* to see how
+it affects program.
+* TODO: server list storage in Location OR users preferences. This
+should be offered as a choice to user.
+*[done]  "AddServer" should be called "Edit server list" or some of edit
+icons on button should be used.
+* getCapabilities should provide not only layer list, but also access
+to any data about layer from capabilities document.
+Comments/description are most important. I.e. for gisnet.lv topo
+service layer name "DTC" (desmit tūkstoši, C sistēma) is meaningful
+only to some folks, still description contains more infromation
+* getCapabilities layers might be in hierarchical system (layer groups)
+
+Design decisions to be made:
+* Should we store EPSG code; preferred image format in server settings?
+* How to determine automatically locations EPSG code? You should ask
+-dev mailing list.
+
+Coding style, variable naming etc. You already know.
+
+
+
+
+Issue reported by Maris, Mail 2
+
+* To display important error messages to user use wx.MessageDialog
+with standard options (OK, ERROR icon). For example, "fill all fields"
+should be changed to popup dialog and it also should list missing
+fields. Like: "Following required fields are missing: <LIST OF
+FIELDS>"
+*[done] Saving a new server should send a signal to main windows (wmsFrame)
+server list to update itself.
+*[done] Closing main application window (wmsFrame) should close also AddServer dialog.
+* If user has edited some of server fields without Save or SaveNew,
+onClose should ask "There are unsaved changes. Save/SaveNew"
+
+More important:
+*[done] getCapabilities response should be validated. HTTP code 200 doesn't
+mean it's a valid response. I.e. create a server with url
+http://slashdot.org and it will threat it's responses as
+getCapabilities documents!
+*[done] server name might contain characters that are forbidden in XML. They
+should be encoded/escaped on save and decoded/unescaped on XML read.
+I.e. create a server called </servername> and see how it breaks Your
+XML...
+
++ some of previous issues...
+
+
+
+
+
+
+
+
+

Modified: grass-addons/grass7/gui/wxpython/wx.wms/addserver.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.wms/addserver.py	2011-08-06 16:03:47 UTC (rev 47469)
+++ grass-addons/grass7/gui/wxpython/wx.wms/addserver.py	2011-08-06 19:37:29 UTC (rev 47470)
@@ -8,6 +8,7 @@
 from BeautifulSoup import BeautifulSoup, Tag, NavigableString, BeautifulStoneSoup
 from ServerInfoAPIs import addServerInfo, removeServerInfo, updateServerInfo, initServerInfoBase, getAllRows
 from LoadConfig import loadConfigFile
+from savepopup import SavePopUp
 
 
 # begin wxGlade: extracode
@@ -45,6 +46,10 @@
         self.__do_layout()
 
         self.Bind(wx.EVT_COMBOBOX, self.OnServerList, self.ServerList)
+        self.Bind(wx.EVT_TEXT, self.OnText, self.ServerNameText)
+        self.Bind(wx.EVT_TEXT, self.OnText, self.URLText)
+        self.Bind(wx.EVT_TEXT, self.OnText, self.UsernameText)
+        self.Bind(wx.EVT_TEXT, self.OnText, self.PasswordText)
         self.Bind(wx.EVT_BUTTON, self.OnSave, self.Save)
         self.Bind(wx.EVT_BUTTON, self.OnRemove, self.Remove)
         self.Bind(wx.EVT_BUTTON, self.OnAddNew, self.AddNew)
@@ -62,7 +67,11 @@
             return
         self.Bind(wx.EVT_CLOSE, self.OnQuit)
         self.__populate_URL_List(self.ServerList)
-        Publisher().subscribe(self.onWMSMenuClose, ("WMS_Menu_Close"))
+        Publisher().subscribe(self.OnWMSMenuClose, ("WMS_Menu_Close"))
+        Publisher().subscribe(self.OnPopupSaveRequest, ("PopupSaveRequest"))
+        Publisher().subscribe(self.OnPopupNotSaveRequest, ("PopupNotSaveRequest"))
+        Publisher().subscribe(self.OnPopupCancelRequest, ("PopupCancelRequest"))
+        self.editOn = False
         #sudeep code ends
 
     def __set_properties(self):
@@ -122,52 +131,45 @@
         self.SetSizer(sizer_1)
         self.Layout()
         # end wxGlade
-
-    def __populate_URL_List(self, ComboBox):
-        self.servers = getAllRows(self.soup)
-        for key, value in self.servers.items():
-            ComboBox.Append(value.servername+self.name_url_delimiter+value.url)
-            #ComboBox.Append(value.servername+" "+value.url)
-        #print self.servers
-        return
-    	''''f = open('serverList.txt','r')
-        lines = f.readlines()
-        self.servers = {}
-        for line in lines:
-            row = line.split()
-            print 'row =' 
-            print row
-            if(len(row) == 4) :
-                servername = row[0]
-                url = row[1]
-                username = row[2]
-                password = row[3]
-                serverdata = ServerData()
-                serverdata.servername = servername
-                serverdata.url = url
-                serverdata.username = username
-                serverdata.password = password
-                self.servers[servername] = serverdata
-                name = row[0]+" "+row[1]
-                print 'yoyo '+name
-                ComboBox.Append(name)
-        f.close()
-        print self.servers'''
         
-    def __update_URL_List(self):
-        self.ServerList.Clear()
-        for key,value in self.servers.iteritems():
-            #name = v.servername+" "+v.url
-            self.ServerList.Append(value.servername+self.name_url_delimiter+value.url)
-            #self.ServerList.Append(name)
-        
     def OnSave(self, event): # wxGlade: ServerAdd.<event_handler>
         #print "Event handler `OnSave' not implemented"
         newServerName = unicode(self.ServerNameText.GetValue())
+        newUrl = self.URLText.GetValue()
+        newUserName = self.UsernameText.GetValue()
+        newPassword = self.PasswordText.GetValue()
+        
+        
         if(newServerName.count(self.name_url_delimiter)>0):
                 print "Warning: UserName cannot consist of "+self.name_url_delimiter
                 print "Please give another username, save failed..."
                 return
+            
+        if(newUrl.count(self.name_url_delimiter)>0):
+                print "Warning: URL cannot consist of "+self.name_url_delimiter
+                print "Change in config file required to use different character as delimeter which doesnot appears in url"
+                return
+            
+        character = '>'
+        if(newServerName.count(character) > 0 or newUrl.count(character) > 0 or newUserName.count(character) > 0 or newPassword.count(character) > 0):
+            print character+' is not allowed in a Field'
+            return
+
+        character = '<'
+        if(newServerName.count(character) > 0 or newUrl.count(character) > 0 or newUserName.count(character) > 0 or newPassword.count(character) > 0):
+            print character+' is not allowed in a Field'
+            return
+        
+        character = '&'
+        if(newServerName.count(character) > 0 or newUrl.count(character) > 0 or newUserName.count(character) > 0 or newPassword.count(character) > 0):
+            print character+' is not allowed in a Field'
+            return
+        
+        print 'before '+newUrl
+        if(not newUrl.startswith('http://')):
+            newUrl = 'http://'+newUrl
+        print 'after '+newUrl
+        
         print newServerName
         print 'check12'
         if(self.servers.has_key(newServerName)):
@@ -177,9 +179,7 @@
         else:
             update = False
             
-        newUrl = self.URLText.GetValue()
-        newUserName = self.UsernameText.GetValue()
-        newPassword = self.PasswordText.GetValue()
+       
         
         serverData = ServerData()
         #self.ServerList.Append(newServerName+" "+newUrl)
@@ -220,7 +220,9 @@
   	    #Update_Url_List(newServerName+" "+newUrl)
         else:
             print "Please Fill servername and url fields"
-        event.Skip()
+        self.editOn = False
+        if(event):
+            event.Skip()
 
     def OnRemove(self, event): # wxGlade: ServerAdd.<event_handler>
         serverName = unicode(self.ServerNameText.GetValue())
@@ -246,7 +248,7 @@
         else:
             print 'No server selected'
         #print "Event handler `OnRemove' not implemented"
-        
+        self.editOn = False
         event.Skip()
 
     def OnAddNew(self, event): # wxGlade: ServerAdd.<event_handler>
@@ -255,34 +257,14 @@
         self.PasswordText.Clear()
         self.URLText.Clear()
         self.UsernameText.Clear()
+        self.editOn = False
         event.Skip()
-        
-    def saveXMLData(self):
-        xml = self.soup.prettify()
-        try:
-            f = open('templist.xml','w')
-            f.write(xml)
-            f.close()
-        except:
-            print 'Unable to write in templist.xml file, Save not successful'
-            return False
-        try:    
-            os.system('chmod 777 ServersList.xml')
-            os.system("cp templist.xml ServersList.xml")
-            #f = open('ServersList.xml','w')
-        except:
-            #print 'cant open file in write mode'
-            print 'cp templist.xml ServersList.xml failed'
-            print 'Save not successful'
-            return False
-        return True
-        
-    def onWMSMenuClose(self, msg):
-        self.Destroy()
-        return
     
     def OnQuit(self, event): # wxGlade: ServerAdd.<event_handler>
         print 'onQuit pressed'
+        if(self.editOn):
+            print "Do you want to save the unsaved changes ?"
+            SavePopUp()
         self.saveXMLData()
         msg = self.servers
         Publisher().sendMessage(("Add_Server_Frame_Closed"), msg)
@@ -318,6 +300,70 @@
         #self.ServerNameText.SetValue(self.servers)
         event.Skip()
 
+    def OnText(self, event): # wxGlade: ServerAdd.<event_handler>
+        self.editOn = True
+        event.Skip()
+    #wxGlade methods ends
+    
+    #Sudeeps methods start
+    def __populate_URL_List(self, ComboBox):
+        self.servers = getAllRows(self.soup)
+        for key, value in self.servers.items():
+            ComboBox.Append(value.servername+self.name_url_delimiter+value.url)
+            #ComboBox.Append(value.servername+" "+value.url)
+        #print self.servers
+        return
+    
+    def __update_URL_List(self):
+        self.ServerList.Clear()
+        for key,value in self.servers.iteritems():
+            #name = v.servername+" "+v.url
+            self.ServerList.Append(value.servername+self.name_url_delimiter+value.url)
+            #self.ServerList.Append(name)
+
+    def saveXMLData(self):
+        xml = self.soup.prettify()
+        try:
+            f = open('templist.xml','w')
+            f.write(xml)
+            f.close()
+        except:
+            print 'Unable to write in templist.xml file, Save not successful'
+            return False
+        try:    
+            os.system('chmod 777 ServersList.xml')
+            os.system("cp templist.xml ServersList.xml")
+            #f = open('ServersList.xml','w')
+        except:
+            #print 'cant open file in write mode'
+            print 'cp templist.xml ServersList.xml failed'
+            print 'Save not successful'
+            return False
+        return True
+        
+    def OnWMSMenuClose(self, msg):
+        self.Close()
+        self.Destroy()
+        return
+    
+    def OnPopupSaveRequest(self, msg):
+        self.OnSave(None)
+        self.saveXMLData()
+        msg = self.servers
+        Publisher().sendMessage(("Add_Server_Frame_Closed"), msg)
+        self.Quit
+        self.Close()
+        #self.Destroy()
+    
+    def OnPopupNotSaveRequest(self, msg):
+        self.saveXMLData()
+        msg = self.servers
+        Publisher().sendMessage(("Add_Server_Frame_Closed"), msg)
+        self.Close()
+        self.Destroy()
+
+    def OnPopupCancelRequest(self, msg):
+        return
 # end of class ServerAdd
 
 def AddServerFrame(parentWMS):

Modified: grass-addons/grass7/gui/wxpython/wx.wms/parse.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.wms/parse.py	2011-08-06 16:03:47 UTC (rev 47469)
+++ grass-addons/grass7/gui/wxpython/wx.wms/parse.py	2011-08-06 19:37:29 UTC (rev 47470)
@@ -24,7 +24,17 @@
 a=f.read()
 print a
 #parsexml(a) '''
-
+def isValidResponse(xml):
+	soup = BeautifulSoup(xml)
+	getCapabilities = soup.findAll('wmt_ms_capabilities')
+	print 'heeeeeeeeereeeeee'
+	print len(getCapabilities)
+	if(len(getCapabilities)==0):
+		print 'False'
+		return False
+	else:
+		print 'True'
+		return True
 def isServiceException(xml):
 	print 'here'
 	#print xml

Added: grass-addons/grass7/gui/wxpython/wx.wms/savepopup.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.wms/savepopup.py	                        (rev 0)
+++ grass-addons/grass7/gui/wxpython/wx.wms/savepopup.py	2011-08-06 19:37:29 UTC (rev 47470)
@@ -0,0 +1,86 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# generated by wxGlade 0.6.3 on Sat Aug  6 14:09:41 2011
+
+import wx
+from wx.lib.pubsub import Publisher
+# begin wxGlade: extracode
+# end wxGlade
+
+
+
+class SaveFrame(wx.Frame):
+    def __init__(self, *args, **kwds):
+        # begin wxGlade: SaveFrame.__init__
+        kwds["style"] = wx.DEFAULT_FRAME_STYLE
+        wx.Frame.__init__(self, *args, **kwds)
+        self.unsaved_label = wx.StaticText(self, -1, "                    You have unsaved changes \n                               Do you want to\n")
+        self.SaveButton = wx.Button(self, -1, "Save")
+        self.DontSaveButton = wx.Button(self, -1, "Don't Save")
+        self.button_3 = wx.Button(self, -1, "Cancel")
+
+        self.__set_properties()
+        self.__do_layout()
+
+        self.Bind(wx.EVT_BUTTON, self.OnSave, self.SaveButton)
+        self.Bind(wx.EVT_BUTTON, self.OnDontSave, self.DontSaveButton)
+        self.Bind(wx.EVT_BUTTON, self.OnCancel, self.button_3)
+        # end wxGlade
+
+    def __set_properties(self):
+        # begin wxGlade: SaveFrame.__set_properties
+        self.SetTitle("frame_1")
+        # end wxGlade
+
+    def __do_layout(self):
+        # begin wxGlade: SaveFrame.__do_layout
+        sizer_2 = wx.BoxSizer(wx.VERTICAL)
+        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
+        sizer_2.Add(self.unsaved_label, 0, 0, 0)
+        sizer_3.Add(self.SaveButton, 0, 0, 0)
+        sizer_3.Add(self.DontSaveButton, 0, 0, 0)
+        sizer_3.Add(self.button_3, 0, 0, 0)
+        sizer_2.Add(sizer_3, 0, wx.EXPAND, 0)
+        self.SetSizer(sizer_2)
+        sizer_2.Fit(self)
+        self.Layout()
+        # end wxGlade
+
+    def OnSave(self, event): # wxGlade: SaveFrame.<event_handler>
+        print "Event handler `OnSave' not implemented!"
+        msg = ''
+        Publisher().sendMessage(("PopupSaveRequest"), msg)
+        event.Skip()
+        self.Destroy()
+
+    def OnDontSave(self, event): # wxGlade: SaveFrame.<event_handler>
+        print "Event handler `OnDontSave' not implemented!"
+        msg = ''
+        Publisher().sendMessage(("PopupNotSaveRequest"), msg)
+        event.Skip()
+        self.Destroy()
+
+    def OnCancel(self, event): # wxGlade: SaveFrame.<event_handler>
+        print "Event handler `OnCancel' not implemented!"
+        msg = ''
+        Publisher().sendMessage(("PopupCancelRequest"), msg)
+        event.Skip()
+        self.Destroy()
+
+# end of class SaveFrame
+
+def SavePopUp():
+    app = wx.PySimpleApp(0)
+    wx.InitAllImageHandlers()
+    dialog_1 = SaveFrame(None, -1, "")
+    app.SetTopWindow(dialog_1)
+    dialog_1.Show()
+    app.MainLoop()
+
+if __name__ == "__main__":
+    app = wx.PySimpleApp(0)
+    wx.InitAllImageHandlers()
+    dialog_1 = SaveFrame(None, -1, "")
+    app.SetTopWindow(dialog_1)
+    dialog_1.Show()
+    app.MainLoop()
\ No newline at end of file

Modified: grass-addons/grass7/gui/wxpython/wx.wms/wmsmenu.py
===================================================================
--- grass-addons/grass7/gui/wxpython/wx.wms/wmsmenu.py	2011-08-06 16:03:47 UTC (rev 47469)
+++ grass-addons/grass7/gui/wxpython/wx.wms/wmsmenu.py	2011-08-06 19:37:29 UTC (rev 47470)
@@ -6,12 +6,13 @@
 from wxPython.wx import *
 from wx.lib.pubsub import Publisher
 from urllib2 import Request, urlopen, URLError, HTTPError
-from parse import parsexml, isServiceException, populateLayerTree
+from parse import parsexml, isServiceException, populateLayerTree, isValidResponse
 from WMSMapDisplay import NewImageFrame
 from addserver import AddServerFrame
 from ServerInfoAPIs import addServerInfo, removeServerInfo, updateServerInfo, initServerInfoBase, getAllRows
 from LoadConfig import loadConfigFile
 
+
 # begin wxGlade: extracode
 # end wxGlade
 
@@ -154,6 +155,12 @@
         try:
             response = urlopen(req)
             xml = response.read()
+            if(not isValidResponse(xml)):
+                print 'Not a valid Get Capabilities reponse'
+                return
+            if(isServiceException(xml)):
+                print 'Service Exception in Get Capabilities'
+                return
             #for testing pruposes
             #f=open('in1.xml','r')
             #xml=f.read()



More information about the grass-commit mailing list