comparison orpg/tools/InterParse.py @ 212:13054be69834 beta

Traipse Beta 'OpenRPG' {100428-00} Traipse is a distribution of OpenRPG that is designed to be easy to setup and go. Traipse also makes it easy for developers to work on code without fear of sacrifice. 'Ornery-Orc' continues the trend of 'Grumpy' and adds fixes to the code. 'Ornery-Orc's main goal is to offer more advanced features and enhance the productivity of the user. Update Summary (Patch-2) New Features: New Namespace method with two new syntaxes New Namespace Internal is context sensitive, always! New Namespace External is 'as narrow as you make it' New Namespace FutureCheck helps ensure you don't receive an incorrect node New PluginDB access for URL2Link plugin New to Forms, they now show their content in Design Mode New to Update Manager, checks Repo for updates on software start Fixes: Fix to Server GUI startup errors Fix to Server GUI Rooms tab updating Fix to Chat and Settings if non existant die roller is picked Fix to Dieroller and .open() used with .vs(). Successes are correctly calculated Fix to Alias Lib's Export to Tree, Open, Save features Fix to alias node, now works properly Fix to Splitter node, minor GUI cleanup Fix to Backgrounds not loading through remote loader Fix to Node name errors Fix to rolling dice in chat Whispers Fix to Splitters Sizing issues Fix to URL2Link plugin, modified regex compilation should remove memory leak Fix to mapy.py, a roll back due to zoomed grid issues Fix to whiteboard_handler, Circles work by you clicking the center of the circle Fix to Servers parse_incoming_dom which was outdated and did not respect XML Fix to a broken link in the server welcome message Fix to InterParse and logger requiring traceback Fix to Update Manager Status Bar Fix to failed image and erroneous pop up
author sirebral
date Wed, 28 Apr 2010 08:08:09 -0500
parents 44ef45e77880
children bb7b9648792c
comparison
equal deleted inserted replaced
194:44ef45e77880 212:13054be69834
1 #!/usr/bin/env python
2 # Copyright (C) 2000-2010 The OpenRPG Project
3 #
4 # openrpg-dev@lists.sourceforge.net
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 # --
20 #
21 # File: InterParse.py
22 # Author:
23 # Maintainer: Tyler Starke (Traipse)
24 # Version:
25 # $Id: InterParse.py,v Traipse 'Ornery-Orc' prof.ebral Exp $
26 #
27 # Description: InterParse = Interpretor Parser. This class parses all of the node referencing.
28 #
29
1 from orpg.orpgCore import component 30 from orpg.orpgCore import component
2 import re 31 import re
3 from orpg.tools.orpg_log import logger 32 from orpg.tools.orpg_log import logger
4 from wx import TextEntryDialog, ID_OK 33 from wx import TextEntryDialog, ID_OK
34 from xml.etree.ElementTree import iselement
5 35
6 class InterParse(): 36 class InterParse():
7 37
8 def __init__(self): 38 def __init__(self):
9 pass 39 pass
10 40
11 def Post(self, s, send=False, myself=False): 41 def Post(self, s, tab=False, send=False, myself=False):
12 s = self.Normalize(s) 42 if not tab: tab = component.get('chat')
13 component.get('chat').set_colors() 43 s = self.Normalize(s, tab)
14 component.get('chat').Post(s, send, myself) 44 tab.set_colors()
15 45 tab.Post(s, send, myself)
16 def Normalize(self, s): 46
17 for plugin_fname in component.get('chat').activeplugins.keys(): 47 def ParseLogic(self, s, node):
18 plugin = component.get('chat').activeplugins[plugin_fname] 48 'Nodes now parse through ParsLogic. Easily add new parse rules right here!!'
49 s = self.NameSpaceE(s)
50 s = self.NameSpaceI(s, node)
51 s = self.NodeMap(s, node)
52 s = self.NodeParent(s, node.get('map'))
53 return s
54
55 def Normalize(self, s, tab):
56 for plugin_fname in tab.activeplugins.keys():
57 plugin = tab.activeplugins[plugin_fname]
19 try: s = plugin.pre_parse(s) 58 try: s = plugin.pre_parse(s)
20 except Exception, e: 59 except Exception, e:
21 if str(e) != "'module' object has no attribute 'post_msg'": 60 if str(e) != "'module' object has no attribute 'post_msg'":
22 logger.general(traceback.format_exc()) 61 #logger.general(traceback.format_exc())
23 logger.general("EXCEPTION: " + str(e)) 62 logger.general("EXCEPTION: " + str(e))
24 if component.get('chat').parsed == 0: 63 if tab.parsed == 0:
64 s = self.NameSpaceE(s)
25 s = self.Node(s) 65 s = self.Node(s)
26 s = self.Dice(s) 66 s = self.Dice(s)
27 s = self.Filter(s) 67 s = self.Filter(s, tab)
28 component.get('chat').parsed = 1 68 tab.parsed = 1
29 return s 69 return s
30 70
31 def Filter(self, s): 71 def Filter(self, s, tab):
32 s = component.get('chat').GetFilteredText(s) 72 s = tab.GetFilteredText(s)
33 return s 73 return s
34 74
35 def Node(self, s): 75 def Node(self, s):
36 """Parses player input for embedded nodes rolls""" 76 """Parses player input for embedded nodes rolls"""
37 cur_loc = 0 77 cur_loc = 0
75 matches = reg.findall(s) 115 matches = reg.findall(s)
76 for i in xrange(0,len(matches)): 116 for i in xrange(0,len(matches)):
77 lb = "Replace '?' with: " 117 lb = "Replace '?' with: "
78 if len(matches[i][0]): 118 if len(matches[i][0]):
79 lb = matches[i][1] + "?: " 119 lb = matches[i][1] + "?: "
80 dlg = TextEntryDialog(self, lb, "Missing Value?") 120 dlg = TextEntryDialog(component.get('chat'), lb, "Missing Value?")
81 dlg.SetValue('') 121 dlg.SetValue('')
82 if matches[i][0] != '': 122 if matches[i][0] != '':
83 dlg.SetTitle("Enter Value for " + matches[i][1]) 123 dlg.SetTitle("Enter Value for " + matches[i][1])
84 if dlg.ShowModal() == ID_OK: newstr = dlg.GetValue() 124 if dlg.ShowModal() == ID_OK: newstr = dlg.GetValue()
85 if newstr == '': newstr = '0' 125 if newstr == '': newstr = '0'
86 s = s.replace(matches[i][0], newstr, 1).replace(matches[i][1], '', 1).replace(matches[i][2], '', 1) 126 s = s.replace(matches[i][0], newstr, 1).replace(matches[i][1], '', 1).replace(matches[i][2], '', 1)
87 dlg.Destroy() 127 dlg.Destroy()
88 return s 128 return s
89 129
130 def LocationCheck(self, node, tree_map, new_map, find):
131 if node == 'Invalid Reference!': return node
132 namespace = node.getiterator('nodehandler'); tr = tree_map.split('::')
133 newstr = ''
134 for name in namespace:
135 try: t = new_map.index(name.get('name'))-1
136 except: t = 0
137 if find[0] == name.get('name'):
138 s = '::'.join(new_map[:len(tr)-t])+'::'+'::'.join(find)
139 newstr = self.NameSpaceE('!&' +s+ '&!')
140 break
141 if newstr != '': return newstr
142 else:
143 del new_map[len(new_map)-1]
144 node = self.get_node(new_map)
145 newstr = self.LocationCheck(node, tree_map, new_map, find)
146 return newstr
147
148 def FutureCheck(self, node, next):
149 future = node.getiterator('nodehandler')
150 for advance in future:
151 if next == advance.get('name'): return True
152 return False
153
154 def NameSpaceI(self, s, node):
155 reg = re.compile("(!=(.*?)=!)")
156 matches = reg.findall(s)
157 tree_map = node.get('map')
158 for i in xrange(0,len(matches)):
159 ## Build the new tree_map
160 new_map = tree_map.split('::')
161 find = matches[i][1].split('::')
162 ## Backwards Reference the Parent Children
163 node = self.get_node(new_map)
164 newstr = self.LocationCheck(node, tree_map, new_map, find)
165 s = s.replace(matches[i][0], newstr, 1)
166 return s
167
168 def NameSpaceE(self, s):
169 reg = re.compile("(!&(.*?)&!)")
170 matches = reg.findall(s)
171 newstr = False
172 nodeable = ['rpg_grid_handler', 'container_handler',
173 'group_handler', 'tabber_handler',
174 'splitter_handler', 'form_handler', 'textctrl_handler']
175 for i in xrange(0,len(matches)):
176 find = matches[i][1].split('::')
177 node = component.get('tree').xml_root
178 if not iselement(node):
179 s = s.replace(matches[i][0], 'Invalid Reference!', 1);
180 s = self.NameSpaceE(s)
181 return s
182 for x in xrange(0, len(find)):
183 namespace = node.getiterator('nodehandler')
184 for node in namespace:
185 if find[x] == node.get('name'):
186 if node.get('class') not in nodeable: continue
187 if node.get('class') == 'rpg_grid_handler':
188 try: newstr = self.NameSpaceGrid(find[x+1], node); break
189 except: newstr = 'Invalid Grid Reference!'
190 try:
191 if self.FutureCheck(node, find[x+1]): break
192 else: continue
193 except:
194 if x == len(find)-1:
195 if node.find('text') != None: newstr = str(node.find('text').text)
196 else: newstr = 'Invalid Reference!'
197 break
198 else: break
199 if not newstr: newstr = 'Invalid Reference!'
200 s = s.replace(matches[i][0], newstr, 1)
201 s = self.ParseLogic(s, node)
202 return s
203
204 def NameSpaceGrid(self, s, node):
205 cell = tuple(s.strip('(').strip(')').split(','))
206 grid = node.find('grid')
207 rows = grid.findall('row')
208 try:
209 col = rows[int(self.Dice(cell[0]))-1].findall('cell')
210 s = self.ParseLogic(col[int(self.Dice(cell[1]))-1].text, node) or 'No Cell Data'
211 except: s = 'Invalid Grid Reference!'
212 return s
213
90 def NodeMap(self, s, node): 214 def NodeMap(self, s, node):
91 """Parses player input for embedded nodes rolls""" 215 """Parses player input for embedded nodes rolls"""
92 cur_loc = 0 216 cur_loc = 0
93 reg = re.compile("(!!(.*?)!!)") 217 reg = re.compile("(!!(.*?)!!)")
94 matches = reg.findall(s) 218 matches = reg.findall(s)
110 ## Build the new tree_map 234 ## Build the new tree_map
111 new_map = tree_map.split('::') 235 new_map = tree_map.split('::')
112 del new_map[len(new_map)-1] 236 del new_map[len(new_map)-1]
113 parent_map = matches[i][1].split('::') 237 parent_map = matches[i][1].split('::')
114 ## Backwards Reference the Parent Children 238 ## Backwards Reference the Parent Children
115 child_node = self.get_node('::'.join(new_map)) 239 child_node = self.get_node(new_map)
116 newstr = self.get_root(child_node, tree_map, new_map, parent_map) 240 newstr = self.get_root(child_node, tree_map, new_map, parent_map)
117 s = s.replace(matches[i][0], newstr, 1) 241 s = s.replace(matches[i][0], newstr, 1)
118 s = self.Node(s) 242 s = self.Node(s)
119 return s 243 return s
120 244
128 if parent_map[0] == root.get('name'): 252 if parent_map[0] == root.get('name'):
129 newstr = '!@' + '::'.join(new_map[:len(tr)-t]) + '::' + '::'.join(parent_map) + '@!' 253 newstr = '!@' + '::'.join(new_map[:len(tr)-t]) + '::' + '::'.join(parent_map) + '@!'
130 if newstr != '': return newstr 254 if newstr != '': return newstr
131 else: 255 else:
132 del new_map[len(new_map)-1] 256 del new_map[len(new_map)-1]
133 child_node = self.get_node('::'.join(new_map)) 257 child_node = self.get_node(new_map)
134 newstr = self.get_root(child_node, tree_map, new_map, parent_map) 258 newstr = self.get_root(child_node, tree_map, new_map, parent_map)
135 return newstr 259 return newstr
136 260
137 def get_node(self, s): 261 def get_node(self, path):
138 return_node = 'Invalid Reference!' 262 return_node = 'Invalid Reference!'
139 value = "" 263 value = ""
140 path = s.split('::')
141 depth = len(path) 264 depth = len(path)
142 try: node = component.get('tree').tree_map[path[0]]['node'] 265 try: node = component.get('tree').tree_map[path[0]]['node']
143 except Exception, e: return return_node 266 except Exception, e: return return_node
144 return_node = self.resolve_get_loop(node, path, 1, depth) 267 return_node = self.resolve_get_loop(node, path, 1, depth)
145 return return_node 268 return return_node
146 269
147 def resolve_get_loop(self, node, path, step, depth): 270 def resolve_get_loop(self, node, path, step, depth):
148 if step == depth: return node 271 if step == depth: return node
149 else: 272 else:
150 child_list = node.findall('nodehandler') 273 child_list = node.getchildren()
151 for child in child_list: 274 for child in child_list:
152 if step == depth: break 275 if step == depth: break
153 if child.get('name') == path[step]: 276 if child.get('name') == path[step]:
154 node = self.resolve_get_loop(child, path, step+1, depth) 277 node = self.resolve_get_loop(child, path, step+1, depth)
155 return node 278 return node
193 if self.passed == False: 316 if self.passed == False:
194 self.passed = True 317 self.passed = True
195 if node.get('class') == 'textctrl_handler': 318 if node.get('class') == 'textctrl_handler':
196 s = str(node.find('text').text) 319 s = str(node.find('text').text)
197 else: s = 'Nodehandler for '+ node.get('class') + ' not done!' or 'Invalid Reference!' 320 else: s = 'Nodehandler for '+ node.get('class') + ' not done!' or 'Invalid Reference!'
198 else: 321 else: s = ''
199 s = '' 322 s = self.ParseLogic(s, node)
200 s = self.NodeMap(s, node)
201 s = self.NodeParent(s, node.get('map'))
202 return s 323 return s
203 324
204 def resolve_grid(self, node, path, step, depth): 325 def resolve_grid(self, node, path, step, depth):
205 if step == depth: 326 if step == depth:
206 return 'Invalid Grid Reference!' 327 return 'Invalid Grid Reference!'
207 cell = tuple(path[step].strip('(').strip(')').split(',')) 328 cell = tuple(path[step].strip('(').strip(')').split(','))
208 grid = node.find('grid') 329 grid = node.find('grid')
209 rows = grid.findall('row') 330 rows = grid.findall('row')
210 col = rows[int(self.Dice(cell[0]))-1].findall('cell') 331 col = rows[int(self.Dice(cell[0]))-1].findall('cell')
211 try: s = self.NodeMap(col[int(self.Dice(cell[1]))-1].text, node) or 'No Cell Data' 332 try: s = self.ParseLogic(col[int(self.Dice(cell[1]))-1].text, node) or 'No Cell Data'
212 except: s = 'Invalid Grid Reference!' 333 except: s = 'Invalid Grid Reference!'
213 return s 334 return s
214 335
215 def resolve_cust_loop(self, node, path, step, depth): 336 def resolve_cust_loop(self, node, path, step, depth):
216 s = 'Invalid Reference!' 337 s = 'Invalid Reference!'