Mercurial > traipse_dev
comparison orpg/networking/meta_server_lib.py @ 135:dcf4fbe09b70 beta
Traipse Beta 'OpenRPG' {091010-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 (Beta)
Added Bookmarks
Fix to Remote Admin Commands
Minor fix to text based Server
Fix to Pretty Print, from Core
Fix to Splitter Nodes not being created
Fix to massive amounts of images loading, from Core
Added 'boot' command to remote admin
Added confirmation window for sent nodes
Minor changes to allow for portability to an OpenSUSE linux OS
Miniatures Layer pop up box allows users to turn off Mini labels, from FlexiRPG
Zoom Mouse plugin added
Images added to Plugin UI
Switching to Element Tree
Map efficiency, from FlexiRPG
Added Status Bar to Update Manager
default_manifest.xml renamed to default_upmana.xml
Cleaner clode for saved repositories
New TrueDebug Class in orpg_log (See documentation for usage)
Mercurial's hgweb folder is ported to upmana
**Pretty important update that can help remove thousands of dead children from your gametree.
**Children, <forms />, <group_atts />, <horizontal />, <cols />, <rows />, <height />, etc... are all tags now. Check your gametree and
look for dead children!!
**New Gamtree Recusion method, mapping, and context sensitivity. !!Alpha - Watch out for infinite loops!!
author | sirebral |
---|---|
date | Tue, 10 Nov 2009 14:11:28 -0600 |
parents | 7ed4979cc1cf |
children | 6081bdc2b8d5 |
comparison
equal
deleted
inserted
replaced
101:394ebb3b6a0f | 135:dcf4fbe09b70 |
---|---|
35 | 35 |
36 from orpg.orpg_version import PROTOCOL_VERSION | 36 from orpg.orpg_version import PROTOCOL_VERSION |
37 from orpg.orpgCore import component | 37 from orpg.orpgCore import component |
38 from orpg.tools.validate import validate | 38 from orpg.tools.validate import validate |
39 from orpg.dirpath import dir_struct | 39 from orpg.dirpath import dir_struct |
40 import urllib | 40 |
41 import orpg.minidom | 41 import urllib, time, sys, traceback, re |
42 #import orpg.minidom | |
43 | |
42 from threading import * | 44 from threading import * |
43 import time | 45 from random import uniform |
44 import sys | 46 from urllib import urlopen, urlencode |
45 import random | 47 from orpg.tools.orpg_log import debug |
46 import traceback | 48 |
47 import re | 49 from xml.etree.ElementTree import Element, fromstring |
48 | 50 |
49 metacache_lock = RLock() | 51 metacache_lock = RLock() |
50 | 52 |
51 def get_server_dom(data=None,path=None): | 53 def get_server_dom(data=None,path=None, string=False): |
52 # post data at server and get the resulting DOM | 54 # post data at server and get the resulting DOM |
53 | 55 #debug() |
54 if path == None: | 56 if path == None: |
55 # get meta server URI | 57 # get meta server URI |
56 path = getMetaServerBaseURL() | 58 path = getMetaServerBaseURL() |
57 | 59 |
58 # POST the data | 60 # POST the data |
60 print | 62 print |
61 print "Sending the following POST info to Meta at " + path + ":" | 63 print "Sending the following POST info to Meta at " + path + ":" |
62 print "==========================================" | 64 print "==========================================" |
63 print data | 65 print data |
64 print | 66 print |
65 file = urllib.urlopen(path, data) | 67 file = urlopen(path, data) |
66 data = file.read() | 68 data = file.read() |
67 file.close() | 69 file.close() |
68 | 70 |
69 # Remove any leading or trailing data. This can happen on some satellite connections | 71 # Remove any leading or trailing data. This can happen on some satellite connections |
70 p = re.compile('(<servers>.*?</servers>)',re.DOTALL|re.IGNORECASE) | 72 p = re.compile('(<servers>.*?</servers>)',re.DOTALL|re.IGNORECASE) |
76 print "Got this string from the Meta at " + path + ":" | 78 print "Got this string from the Meta at " + path + ":" |
77 print "===============================================" | 79 print "===============================================" |
78 print data | 80 print data |
79 print | 81 print |
80 # build dom | 82 # build dom |
81 xml = component.get('xml') | 83 etreeEl = data |
82 xml_dom = xml.parseXml(data) | 84 if not string: return fromstring(etreeEl) |
83 xml_dom = xml_dom._get_documentElement() | 85 else: return etreeEl |
84 return xml_dom | 86 |
85 | 87 def post_server_data(name, realHostName=None): |
86 def post_server_data( name, realHostName=None): | 88 #debug() |
87 if realHostName: | 89 if realHostName: data = urlencode({"server_data[name]":name, |
88 data = urllib.urlencode( {"server_data[name]":name, | |
89 "server_data[version]":PROTOCOL_VERSION, | 90 "server_data[version]":PROTOCOL_VERSION, |
90 "act":"new", | 91 "act":"new", |
91 "REMOTE_ADDR": realHostName } ) | 92 "REMOTE_ADDR": realHostName }) |
92 | 93 # print "Letting meta server decide the hostname to list..." |
93 else: | 94 else: data = urlencode({"server_data[name]":name, |
94 #print "Letting meta server decide the hostname to list..." | |
95 data = urllib.urlencode( {"server_data[name]":name, | |
96 "server_data[version]":PROTOCOL_VERSION, | 95 "server_data[version]":PROTOCOL_VERSION, |
97 "act":"new"} ) | 96 "act":"new"}) |
98 | 97 path = component.get('settings').get('MetaServerBaseURL') #getMetaServerBaseURL() |
99 #xml_dom = get_server_dom( data , "http://openrpg.sf.net/openrpg_servers.php")#Sourceforge still? | 98 etreeEl = get_server_dom(data, path) |
100 path = component.get('settings').get_setting('MetaServerBaseURL') #getMetaServerBaseURL() | 99 return int(etreeEl.get('id')) |
101 xml_dom = get_server_dom(data, path) | |
102 ret_val = int( xml_dom.getAttribute( "id" ) ) | |
103 return ret_val | |
104 | 100 |
105 def post_failed_connection(id,meta=None,address=None,port=None): | 101 def post_failed_connection(id,meta=None,address=None,port=None): |
102 #debug((meta, address, port)) | |
106 # For now, turning this off. This needs to be re-vamped for | 103 # For now, turning this off. This needs to be re-vamped for |
107 # handling multiple Metas. | 104 # handling multiple Metas. |
108 return 0 | 105 return 0 |
109 #data = urllib.urlencode({"id":id,"act":"failed"}); | 106 #data = urlencode({"id":id,"act":"failed"}); |
110 #xml_dom = get_server_dom(data) | 107 #xml_dom = get_server_dom(data) |
111 #ret_val = int(xml_dom.getAttribute("return")) | 108 #ret_val = int(xml_dom.getAttribute("return")) |
112 #return ret_val | 109 #return ret_val |
113 | 110 |
114 def remove_server(id): | 111 def remove_server(id): |
115 data = urllib.urlencode({"id":id,"act":"del"}); | 112 #debug(id) |
116 xml_dom = get_server_dom(data) | 113 data = urlencode({"id":id,"act":"del"}); |
117 ret_val = int(xml_dom.getAttribute("return")) | 114 etreeEl = get_server_dom(data) |
118 return ret_val | 115 return int(etreeEl.get("return")) |
119 | 116 |
120 | 117 def byStartAttribute(first, second): |
121 def byStartAttribute(first,second): | 118 # This function is used to easily sort a list of nodes by their start time |
122 # This function is used to easily sort a list of nodes | 119 # Ensure there is something to sort with for each |
123 # by their start time | 120 |
124 | 121 first_start = int(first.get('start')) or 0 |
125 if first.hasAttribute("start"): first_start = int(first.getAttribute("start")) | 122 second_start = int(second.get('start')) or 0 |
126 else: first_start = 0 | |
127 | |
128 if second.hasAttribute("start"): second_start = int(second.getAttribute("start")) | |
129 else: second_start = 0 | |
130 | 123 |
131 # Return the result of the cmp function on the two strings | 124 # Return the result of the cmp function on the two strings |
132 return cmp(first_start,second_start) | 125 return cmp(first_start, second_start) |
133 | 126 |
134 def byNameAttribute(first,second): | 127 def byNameAttribute(first, second): |
135 # This function is used to easily sort a list of nodes | 128 # This function is used to easily sort a list of nodes by their name attribute |
136 # by their name attribute | |
137 | |
138 # Ensure there is something to sort with for each | 129 # Ensure there is something to sort with for each |
139 | 130 |
140 if first.hasAttribute("name"): first_name = str(first.getAttribute("name")).lower() | 131 first_name = first.get('name') or '' |
141 else: first_name = "" | 132 second_name = second.get('name') or '' |
142 | 133 |
143 if second.hasAttribute("name"): second_name = str(second.getAttribute("name")).lower() | |
144 else: second_name = "" | |
145 | |
146 # Return the result of the cmp function on the two strings | 134 # Return the result of the cmp function on the two strings |
147 return cmp(first_name,second_name) | 135 return cmp(first_name,second_name) |
148 | 136 |
149 | 137 |
150 def get_server_list(versions = None,sort_by="start"): | 138 def get_server_list(versions = None, sort_by="start"): |
151 data = urllib.urlencode({"version":PROTOCOL_VERSION,"ports":"%"}) | 139 data = urlencode({"version":PROTOCOL_VERSION,"ports":"%"}) |
152 all_metas = getMetaServers(versions,1) # get the list of metas | 140 all_metas = getMetaServers(versions, 1) # get the list of metas |
153 base_meta = getMetaServerBaseURL() | 141 base_meta = getMetaServerBaseURL() |
154 | 142 |
155 #all_metas.reverse() # The last one checked will take precedence, so reverse the order | 143 #all_metas.reverse() # The last one checked will take precedence, so reverse the order |
156 # so that the top one on the actual list is checked last | 144 # so that the top one on the actual list is checked last |
157 | 145 return_hash = {} # this will end up with an amalgamated list of servers |
158 return_hash = {} # this will end up with an amalgamated list of servers | 146 |
159 | 147 for meta in all_metas: # check all of the metas |
160 for meta in all_metas: # check all of the metas | |
161 | |
162 #get the server's xml from the current meta | 148 #get the server's xml from the current meta |
163 bad_meta = 0 | 149 bad_meta = 0 |
164 #print "Getting server list from " + meta + "..." | 150 #print "Getting server list from " + meta + "..." |
165 try: xml_dom = get_server_dom(data=data,path=meta) | 151 try: xml_dom = get_server_dom(data=data, path=meta) |
166 except: | 152 except: bad_meta = 1 #print "Trouble getting servers from " + meta + "..." |
167 #print "Trouble getting servers from " + meta + "..." | 153 if bad_meta: continue |
168 bad_meta = 1 | 154 if base_meta == meta: updateMetaCache(xml_dom) #print "This is our base meta: " + meta |
169 | 155 node_list = xml_dom.findall('server') |
170 if bad_meta: | 156 if len(node_list): # if there are entries in the node list |
171 continue | 157 # otherwise, just loop to next meta |
172 | |
173 if base_meta == meta: | |
174 #print "This is our base meta: " + meta | |
175 updateMetaCache(xml_dom) | |
176 | |
177 node_list = xml_dom.getElementsByTagName('server') | |
178 | |
179 if len(node_list): # if there are entries in the node list | |
180 # otherwise, just loop to next meta | |
181 | 158 |
182 # for each node found, we're going to check the nodes from prior | 159 # for each node found, we're going to check the nodes from prior |
183 # metas in the list. If a match is found, then use the new values. | 160 # metas in the list. If a match is found, then use the new values. |
184 for n in node_list: | 161 for n in node_list: |
185 | |
186 # set them from current node | 162 # set them from current node |
187 | 163 if not n.get('name'): n.set('name','NO_NAME_GIVEN') |
188 if not n.hasAttribute('name'): n.setAttribute('name','NO_NAME_GIVEN') | 164 name = n.get('name') |
189 name = n.getAttribute('name') | 165 if not n.get('num_users'): n.set('num_users','N/A') |
190 if not n.hasAttribute('num_users'): n.setAttribute('num_users','N/A') | 166 num_users = n.get('num_users') |
191 num_users = n.getAttribute('num_users') | 167 if not n.get('address'): n.set('address','NO_ADDRESS_GIVEN') |
192 if not n.hasAttribute('address'): n.setAttribute('address','NO_ADDRESS_GIVEN') | 168 address = n.get('address') |
193 address = n.getAttribute('address') | 169 if not n.get('port'): n.set('port','6774') |
194 if not n.hasAttribute('port'): n.setAttribute('port','6774') | 170 port = n.get('port') |
195 port = n.getAttribute('port') | 171 n.set('meta',meta) |
196 n.setAttribute('meta',meta) | |
197 end_point = str(address) + ":" + str(port) | 172 end_point = str(address) + ":" + str(port) |
198 if return_hash.has_key(end_point): | 173 if return_hash.has_key(end_point): |
199 if META_DEBUG: print "Replacing duplicate server entry at " + end_point | 174 if META_DEBUG: print "Replacing duplicate server entry at " + end_point |
200 return_hash[end_point] = n | 175 return_hash[end_point] = n |
201 | 176 |
202 # At this point, we have an amalgamated list of servers | 177 # At this point, we have an amalgamated list of servers |
203 # Now, we have to construct a new DOM to pass back. | 178 # Now, we have to construct a new DOM to pass back. |
204 | 179 |
205 # Create a servers element | 180 # Create a servers element |
206 return_dom = orpg.minidom.Element("servers") | 181 server_list = Element('servers') |
207 | 182 |
208 # get the nodes stored in return_hash | 183 # get the nodes stored in return_hash |
209 return_list = return_hash.values() | 184 sort_list = return_hash.values() |
210 | 185 |
211 # sort them by their name attribute. Uses byNameAttribute() | 186 # sort them by their name attribute. Uses byNameAttribute() |
212 # defined above as a comparison function | 187 # defined above as a comparison function |
213 | 188 if sort_by == "start": sort_list.sort(byStartAttribute) |
214 if sort_by == "start": return_list.sort(byStartAttribute) | 189 elif sort_by == "name": sort_list.sort(byNameAttribute) |
215 elif sort_by == "name": return_list.sort(byNameAttribute) | |
216 | 190 |
217 # Add each node to the DOM | 191 # Add each node to the DOM |
218 for n in return_list: return_dom.appendChild(n) | 192 for n in sort_list: server_list.append(n) |
219 return return_dom | 193 return server_list |
220 | 194 |
221 ## List Format: | 195 ## List Format: |
222 ## <servers> | 196 ## <servers> |
223 ## <server address=? id=? name=? failed_count=? > | 197 ## <server address=? id=? name=? failed_count=? > |
224 ## </servers> | 198 ## </servers> |
225 | 199 |
226 def updateMetaCache(xml_dom): | 200 def updateMetaCache(xml_dom): |
227 try: | 201 try: |
228 if META_DEBUG: print "Updating Meta Server Cache" | 202 if META_DEBUG: print "Updating Meta Server Cache" |
229 metaservers = xml_dom.getElementsByTagName( 'metaservers' ) # pull out the metaservers bit | 203 metaservers = xml_dom.findall('metaservers') # pull out the metaservers bit |
230 if len(metaservers) == 0: | 204 if len(metaservers) == 0: |
231 cmetalist = getRawMetaList() | 205 cmetalist = getRawMetaList() |
232 xml_dom = get_server_dom(cmetalist[0]) | 206 xml_dom = get_server_dom(cmetalist[0]) |
233 metaservers = xml_dom.getElementsByTagName( 'metaservers' ) | 207 metaservers = xml_dom.findall('metaservers') |
234 authoritative = metaservers[0].getAttribute('auth') | 208 authoritative = metaservers[0].get('auth') |
235 if META_DEBUG: print " Authoritive Meta: "+str(authoritative) | 209 if META_DEBUG: print " Authoritive Meta: "+str(authoritative) |
236 metas = metaservers[0].getElementsByTagName("meta") # get the list of metas | 210 metas = metaservers[0].findall("meta") # get the list of metas |
237 if META_DEBUG: print " Meta List ("+str(len(metas))+" servers)" | 211 if META_DEBUG: print " Meta List ("+str(len(metas))+" servers)" |
238 try: | 212 try: |
239 metacache_lock.acquire() | 213 metacache_lock.acquire() |
240 ini = open(dir_struct["user"]+"metaservers.cache","w") | 214 ini = open(dir_struct["user"]+"metaservers.cache","w") |
241 for meta in metas: | 215 for meta in metas: |
242 if META_DEBUG: print " Writing: "+str(meta.getAttribute('path')) | 216 if META_DEBUG: print " Writing: "+str(meta.get('path')) |
243 ini.write(str(meta.getAttribute('path')) + " " + str(meta.getAttribute('versions')) + "\n") | 217 ini.write(str(meta.get('path')) + " " + str(meta.get('versions')) + "\n") |
244 ini.close() | 218 ini.close() |
245 finally: | 219 finally: |
246 metacache_lock.release() | 220 metacache_lock.release() |
247 except Exception, e: | 221 except Exception, e: |
248 if META_DEBUG: traceback.print_exc() | 222 if META_DEBUG: traceback.print_exc() |
249 print "Meta Server Lib: UpdateMetaCache(): " + str(e) | 223 print "Meta Server Lib: UpdateMetaCache(): " + str(e) |
250 | 224 |
251 def getRawMetaList(): | 225 def getRawMetaList(path=None): |
226 ### Alpha ### | |
227 """This code will allow for a list of metas to be created. Future developement will more integrate the list of metas""" | |
228 if path != None: | |
229 metas = [] | |
230 data = urlencode({"version":PROTOCOL_VERSION,"ports":"%"}) | |
231 xml_dom = get_server_dom(data, path) | |
232 node_list = fromstring(xml_dom).findall('meta_server') | |
233 if len(node_list): | |
234 for n in node_list: | |
235 metas.append(n.get('path')) | |
236 return metas | |
252 try: | 237 try: |
253 try: | 238 try: |
254 metacache_lock.acquire() | 239 metacache_lock.acquire() |
255 # Read in the metas | 240 # Read in the metas |
256 validate.config_file("metaservers.cache","metaservers.cache") | 241 validate.config_file("metaservers.cache","metaservers.cache") |
266 return [] | 251 return [] |
267 | 252 |
268 def getMetaServers(versions = None, pick_random=0): | 253 def getMetaServers(versions = None, pick_random=0): |
269 """ | 254 """ |
270 get meta server URLs as a list | 255 get meta server URLs as a list |
271 | |
272 versions is a list of acceptable version numbers. | 256 versions is a list of acceptable version numbers. |
273 A False truth value will use getMetaServerBaseURL() | 257 A False truth value will use getMetaServerBaseURL() |
274 | |
275 set a default if we have weird reading problems | 258 set a default if we have weird reading problems |
276 default_url = "http://www.openrpg.com/openrpg_servers.php" | 259 default_url = "http://www.openrpg.com/openrpg_servers.php" |
277 """ | 260 """ |
278 | 261 |
262 ### Pre Alpha Design ### | |
263 """ Here is how to handle Multiple Meta servers, and probably the best way to do it. Create an XML file that contains nodes with the various servers. Users will grab that meta data and have the option to connect to multiple meta servers which will allow them to find all the rooms. A check box should be used so if one server faile the users can continue without much lag. When creating a server hosts will need to select a meta to go too. This should be in the final of Ornery Orc.""" | |
279 meta_names = [] | 264 meta_names = [] |
280 | |
281 if(versions): # If versions are supplied, then look in metaservers.conf | 265 if(versions): # If versions are supplied, then look in metaservers.conf |
282 try: | 266 try: |
283 """ | 267 """ |
284 read in the metas from file | 268 read in the metas from file |
285 format of file is one meta entry per line | 269 format of file is one meta entry per line |
286 each entry will be the meta url, followed by one or more version numbers that it | 270 each entry will be the meta url, followed by one or more version numbers that it |
287 handle. Generally, this will be either a 1 for the original Meta format, or | 271 handle. Generally, this will be either a 1 for the original Meta format, or |
288 2 for the new one. | 272 2 for the new one. |
289 """ | 273 """ |
290 | |
291 # Read in the metas | 274 # Read in the metas |
275 #Adding a path object will attempt to look for a meta_network. | |
292 metas = getRawMetaList() | 276 metas = getRawMetaList() |
293 #print str(metas) | |
294 | 277 |
295 # go through each one to check if it should be returned, based on the | 278 # go through each one to check if it should be returned, based on the |
296 # version numbers allowed. | 279 # version numbers allowed. |
297 for meta in metas: | 280 for meta in metas: |
298 | |
299 # split the line on whitespace | 281 # split the line on whitespace |
300 # obviously, your meta servers urls shouldn't contain whitespace. duh. | 282 # obviously, your meta servers urls shouldn't contain whitespace. duh. |
301 words = meta.split() | 283 words = meta.split() |
302 success = 0 # init success flag for version check | 284 success = 0 # init success flag for version check |
303 for version in versions: # run through each allowed version from caller | 285 for version in versions: # run through each allowed version from caller |
314 # print "Warning!!\nNo valid metaservers cached." | 296 # print "Warning!!\nNo valid metaservers cached." |
315 # print "Using meta from MetaServerBaseURL: " + default_meta + "\n" | 297 # print "Using meta from MetaServerBaseURL: " + default_meta + "\n" |
316 # if we have more than one and want a random one | 298 # if we have more than one and want a random one |
317 elif pick_random: | 299 elif pick_random: |
318 if META_DEBUG: print "choosing random meta from: " + str(meta_names) | 300 if META_DEBUG: print "choosing random meta from: " + str(meta_names) |
319 i = int(random.uniform(0,len(meta_names))) | 301 i = int(uniform(0,len(meta_names))) |
320 #meta = meta_names[i] | 302 #meta = meta_names[i] |
321 meta_names = [meta_names[i]] | 303 meta_names = [meta_names[i]] |
322 if META_DEBUG: print "using: " + str(meta_names) | 304 if META_DEBUG: print "using: " + str(meta_names) |
323 else: | 305 else: |
324 if META_DEBUG: print "using all metas: " + str(meta_names) | 306 if META_DEBUG: print "using all metas: " + str(meta_names) |
345 tree = xml.parseXml(txt)._get_documentElement() | 327 tree = xml.parseXml(txt)._get_documentElement() |
346 ini.close() | 328 ini.close() |
347 node_list = tree.getElementsByTagName("MetaServerBaseURL") | 329 node_list = tree.getElementsByTagName("MetaServerBaseURL") |
348 if node_list: | 330 if node_list: |
349 url = node_list[0].getAttribute("value") | 331 url = node_list[0].getAttribute("value") |
350 | |
351 # allow tree to be collected | 332 # allow tree to be collected |
352 try: tree.unlink() | 333 try: tree.unlink() |
353 except: pass | 334 except: pass |
354 | 335 |
355 except Exception,e: | 336 except Exception,e: |
389 Because of this fact, there are some methods from wxThread | 370 Because of this fact, there are some methods from wxThread |
390 that I implemented to minimize changes to the code I had | 371 that I implemented to minimize changes to the code I had |
391 just written, i.e. TestDeleteStatus() and Delete() | 372 just written, i.e. TestDeleteStatus() and Delete() |
392 """ | 373 """ |
393 | 374 |
394 def __init__(self,name=None,realHostName=None,num_users = "Hmmm",MetaPath=None,port=6774,register_callback=None): | 375 def __init__(self, name=None, realHostName=None, num_users="0", |
395 | 376 MetaPath=None, port=6774, register_callback=None): |
396 Thread.__init__(self,name="registerThread") | 377 Thread.__init__(self, name="registerThread") |
397 self.rlock = RLock() # Re-entrant lock used to make this class thread safe | 378 self.rlock = RLock() # Re-entrant lock used to make this class thread safe |
398 self.die_event = Event() # The main loop in run() will wait with timeout on this | 379 self.die_event = Event() # The main loop in run() will wait with timeout on this |
399 if name: | 380 self.name = name or 'Unnamed Server' # Name that the server want's displayed on the Meta |
400 self.name = name # Name that the server want's displayed on the Meta | 381 # But use Unnamed Server if for some crazy reason |
401 else: | 382 # no name is passed to the constructor |
402 self.name = "Unnamed server" # But use this if for some crazy reason no name is | 383 self.num_users = num_users # the number of users currently on this server |
403 # passed to the constructor | |
404 self.num_users = num_users # the number of users currently on this server | |
405 self.realHostName = realHostName # Name to advertise for connection | 384 self.realHostName = realHostName # Name to advertise for connection |
406 self.id = "0" # id returned from Meta. Defaults to "0", which | 385 self.id = "0" # id returned from Meta. Defaults to "0", which |
407 # indicates a new registration. | 386 # indicates a new registration. |
408 self.cookie = "0" # cookie returned from Meta. Defaults to "0",which | 387 self.cookie = "0" # cookie returned from Meta. Defaults to "0", which |
409 # indicates a new registration. | 388 # indicates a new registration. |
410 self.interval = 0 # interval returned from Meta. Is how often to | 389 self.interval = 0 # interval returned from Meta. Is how often to |
411 # re-register, in minutes. | 390 # re-register, in minutes. |
412 self.destroy = 0 # Used to flag that this thread should die | 391 self.destroy = 0 # Used to flag that this thread should die |
413 self.port = str(port) | 392 self.port = str(port) |
420 | 399 |
421 Also, if MetaPath is specified, then use that. Makes | 400 Also, if MetaPath is specified, then use that. Makes |
422 it easier to have multiple registerThreads going to keep the server registered | 401 it easier to have multiple registerThreads going to keep the server registered |
423 on multiple (compatible) Metas. | 402 on multiple (compatible) Metas. |
424 """ | 403 """ |
425 | 404 if MetaPath == None: self.path = getMetaServerBaseURL() # Do this if no Meta specified |
426 if MetaPath == None: | 405 else: self.path = MetaPath |
427 self.path = getMetaServerBaseURL() # Do this if no Meta specified | |
428 else: | |
429 self.path = MetaPath | |
430 | 406 |
431 def getIdAndCookie(self): | 407 def getIdAndCookie(self): |
432 return self.id, self.cookie | 408 return self.id, self.cookie |
433 | 409 |
434 def TestDeleteStatus(self): | 410 def TestDeleteStatus(self): |
435 try: | 411 try: |
436 self.rlock.acquire() | 412 self.rlock.acquire() |
437 return self.die_event.isSet() | 413 return self.die_event.isSet() |
438 finally: | 414 finally: self.rlock.release() |
439 self.rlock.release() | |
440 | 415 |
441 def Delete(self): | 416 def Delete(self): |
442 try: | 417 try: |
443 self.rlock.acquire() | 418 self.rlock.acquire() |
444 self.die_event.set() | 419 self.die_event.set() |
445 finally: | 420 finally: self.rlock.release() |
446 self.rlock.release() | |
447 | 421 |
448 def run(self): | 422 def run(self): |
449 """ | 423 """ |
450 This method gets called by Thread implementation | 424 This method gets called by Thread implementation |
451 when self.start() is called to begin the thread's | 425 when self.start() is called to begin the thread's |
453 | 427 |
454 We will basically enter a loop that continually | 428 We will basically enter a loop that continually |
455 re-registers this server and sleeps Interval | 429 re-registers this server and sleeps Interval |
456 minutes until the thread is ordered to die in place | 430 minutes until the thread is ordered to die in place |
457 """ | 431 """ |
458 while(not self.TestDeleteStatus()): # Loop while until told to die | 432 while(not self.TestDeleteStatus()): # Loop while until told to die |
459 # Otherwise, call thread safe register(). | 433 # Otherwise, call thread safe register(). |
460 self.register(self.name, self.realHostName, self.num_users) | 434 self.register(self.name, self.realHostName, self.num_users) |
461 if META_DEBUG: print "Sent Registration Data" | 435 if META_DEBUG: print "Sent Registration Data" |
462 # register() will end up setting the state variables | 436 # register() will end up setting the state variables |
463 # for us, including self.interval. | 437 # for us, including self.interval. |
464 try: | 438 try: |
465 self.rlock.acquire() # Serialize access to this state information | 439 self.rlock.acquire() # Serialize access to this state information |
466 | 440 |
467 if self.interval >= 3: # If the number of minutes is one or greater | 441 if self.interval >= 3: # If the number of minutes is one or greater |
468 self.interval -= 1 # wake up with 30 seconds left to re-register | 442 self.interval -= 1 # wake up with 30 seconds left to re-register |
469 else: | 443 else: |
470 self.interval = .5 # Otherwise, we probably experienced some kind | 444 self.interval = .5 # Otherwise, we probably experienced some kind |
471 # of error from the Meta in register(). Sleep | 445 # of error from the Meta in register(). Sleep |
472 # for 6 seconds and start from scratch. | 446 # for 6 seconds and start from scratch. |
473 | 447 |
474 finally: # no matter what, release the lock | 448 finally: self.rlock.release() # no matter what, release the lock |
475 self.rlock.release() | |
476 # Wait interval minutes for a command to die | 449 # Wait interval minutes for a command to die |
477 die_signal = self.die_event.wait(self.interval*60) | 450 die_signal = self.die_event.wait(self.interval*60) |
478 | 451 |
479 # If we get past the while loop, it's because we've been asked to die, | 452 # If we get past the while loop, it's because we've been asked to die, |
480 # so just let run() end. Once this occurs, the thread is dead and | 453 # so just let run() end. Once this occurs, the thread is dead and |
499 try: | 472 try: |
500 self.rlock.acquire() | 473 self.rlock.acquire() |
501 if not self.isAlive(): # check to see if this thread is dead | 474 if not self.isAlive(): # check to see if this thread is dead |
502 return 1 # If so, return an error result | 475 return 1 # If so, return an error result |
503 # Do the actual unregistering here | 476 # Do the actual unregistering here |
504 data = urllib.urlencode( {"server_data[id]":self.id, | 477 data = urlencode( {"server_data[id]":self.id, |
505 "server_data[cookie]":self.cookie, | 478 "server_data[cookie]":self.cookie, |
506 "server_data[version]":PROTOCOL_VERSION, | 479 "server_data[version]":PROTOCOL_VERSION, |
507 "act":"unregister"} ) | 480 "act":"unregister"} ) |
508 try: | 481 try: # this POSTS the request and returns the result |
509 xml_dom = get_server_dom(data=data, path=self.path) # this POSTS the request and returns the result | 482 xml_dom = get_server_dom(data=data, path=self.path) |
510 if xml_dom.hasAttribute("errmsg"): | 483 if xml_dom.get("errmsg"): |
511 print "Error durring unregistration: " + xml_dom.getAttribute("errmsg") | 484 print "Error durring unregistration: " + xml_dom.get("errmsg") |
512 except: | 485 except: |
513 if META_DEBUG: print "Problem talking to Meta. Will go ahead and die, letting Meta remove us." | 486 if META_DEBUG: print "Problem talking to Meta. Will go ahead and die, letting Meta remove us." |
514 # If there's an error, echo it to the console | 487 # If there's an error, echo it to the console |
515 | 488 |
516 # No special handling is required. If the de-registration worked we're done. If | 489 # No special handling is required. If the de-registration worked we're done. If |
522 except: pass | 495 except: pass |
523 return 0 | 496 return 0 |
524 finally: self.rlock.release() | 497 finally: self.rlock.release() |
525 | 498 |
526 def register(self, name=None, realHostName=None, num_users=None): | 499 def register(self, name=None, realHostName=None, num_users=None): |
500 #debug((name, realHostName, num_users)) | |
527 """ | 501 """ |
528 Designed to handle the registration, both new and | 502 Designed to handle the registration, both new and |
529 repeated. | 503 repeated. |
530 | 504 |
531 It is intended to be called once every interval | 505 It is intended to be called once every interval |
543 if name: self.name = name | 517 if name: self.name = name |
544 if num_users != None: self.num_users = num_users | 518 if num_users != None: self.num_users = num_users |
545 if realHostName: self.realHostName = realHostName | 519 if realHostName: self.realHostName = realHostName |
546 # build POST data | 520 # build POST data |
547 if self.realHostName: | 521 if self.realHostName: |
548 data = urllib.urlencode( {"server_data[id]":self.id, | 522 data = urlencode( {"server_data[id]":self.id, |
549 "server_data[cookie]":self.cookie, | 523 "server_data[cookie]":self.cookie, |
550 "server_data[name]":self.name, | 524 "server_data[name]":self.name, |
551 "server_data[port]":self.port, | 525 "server_data[port]":self.port, |
552 "server_data[version]":PROTOCOL_VERSION, | 526 "server_data[version]":PROTOCOL_VERSION, |
553 "server_data[num_users]":self.num_users, | 527 "server_data[num_users]":self.num_users, |
554 "act":"register", | 528 "act":"register", |
555 "server_data[address]": self.realHostName } ) | 529 "server_data[address]": self.realHostName } ) |
556 else: | 530 else: |
557 if META_DEBUG: print "Letting meta server decide the hostname to list..." | 531 if META_DEBUG: print "Letting meta server decide the hostname to list..." |
558 data = urllib.urlencode( {"server_data[id]":self.id, | 532 data = urlencode( {"server_data[id]":self.id, |
559 "server_data[cookie]":self.cookie, | 533 "server_data[cookie]":self.cookie, |
560 "server_data[name]":self.name, | 534 "server_data[name]":self.name, |
561 "server_data[port]":self.port, | 535 "server_data[port]":self.port, |
562 "server_data[version]":PROTOCOL_VERSION, | 536 "server_data[version]":PROTOCOL_VERSION, |
563 "server_data[num_users]":self.num_users, | 537 "server_data[num_users]":self.num_users, |
564 "act":"register"} ) | 538 "act":"register"} ) |
565 try: | 539 try: # this POSTS the request and returns the result |
566 xml_dom = get_server_dom(data=data,path=self.path) # this POSTS the request and returns the result | 540 etreeEl = get_server_dom(data=data, path=self.path) |
541 #debug(etreeEl) | |
567 except: | 542 except: |
568 if META_DEBUG: print "Problem talking to server. Setting interval for retry ..." | 543 if META_DEBUG: print "Problem talking to server. Setting interval for retry ..." |
569 if META_DEBUG: print data | 544 if META_DEBUG: print data |
570 if META_DEBUG: print | 545 if META_DEBUG: print |
571 self.interval = 0 | 546 self.interval = 0 |
582 the main thread calls register(). | 557 the main thread calls register(). |
583 """ | 558 """ |
584 return 0 # indicates that it was okay to call, not that no errors occurred | 559 return 0 # indicates that it was okay to call, not that no errors occurred |
585 | 560 |
586 # If there is a DOM returned .... | 561 # If there is a DOM returned .... |
587 if xml_dom: | 562 if etreeEl: |
563 #debug(etreeEl) | |
588 # If there's an error, echo it to the console | 564 # If there's an error, echo it to the console |
589 if xml_dom.hasAttribute("errmsg"): | 565 if etreeEl.get("errmsg"): |
590 print "Error durring registration: " + xml_dom.getAttribute("errmsg") | 566 print "Error durring registration: " + etreeEl.get("errmsg") |
591 if META_DEBUG: print data | 567 if META_DEBUG: print data |
592 if META_DEBUG: print | 568 if META_DEBUG: print |
593 """ | 569 """ |
594 No special handling is required. If the registration worked, id, cookie, and interval | 570 No special handling is required. If the registration worked, id, cookie, and interval |
595 can be stored and used for the next time. | 571 can be stored and used for the next time. |
607 the interval will be less than 1, and the main thread's while loop will reset it | 583 the interval will be less than 1, and the main thread's while loop will reset it |
608 to 6 seconds for the next retry. | 584 to 6 seconds for the next retry. |
609 Is it wrong to have a method where there's more comments than code? :) | 585 Is it wrong to have a method where there's more comments than code? :) |
610 """ | 586 """ |
611 try: | 587 try: |
612 self.interval = int(xml_dom.getAttribute("interval")) | 588 self.interval = int(etreeEl.get("interval")) |
613 self.id = xml_dom.getAttribute("id") | 589 self.id = etreeEl.get("id") |
614 self.cookie = xml_dom.getAttribute("cookie") | 590 self.cookie = etreeEl.get("cookie") |
615 if not xml_dom.hasAttribute("errmsg"): | 591 if not etreeEl.get("errmsg"): updateMetaCache(xml_dom) |
616 updateMetaCache(xml_dom) | |
617 except: | 592 except: |
618 if META_DEBUG: print | 593 if META_DEBUG: print |
619 if META_DEBUG: print "OOPS! Is the Meta okay? It should be returning an id, cookie, and interval." | 594 if META_DEBUG: print "OOPS! Is the Meta okay? It should be returning an id, cookie, and interval." |
620 if META_DEBUG: print "Check to see what it really returned.\n" | 595 if META_DEBUG: print "Check to see what it really returned.\n" |
621 # Let xml_dom get garbage collected | 596 # Let xml_dom get garbage collected |
622 try: | 597 try: xml_dom.unlink() |
623 xml_dom.unlink() | 598 except: pass |
624 except: | |
625 pass | |
626 else: # else if no DOM is returned from get_server_dom() | 599 else: # else if no DOM is returned from get_server_dom() |
627 print "Error - no DOM constructed from Meta message!" | 600 print "Error - no DOM constructed from Meta message!" |
628 return 0 # Let caller know it was okay to call us | 601 return 0 # Let caller know it was okay to call us |
629 finally: | 602 finally: self.rlock.release() |
630 self.rlock.release() | |
631 # End of class registerThread | 603 # End of class registerThread |
632 ################################################################################ | 604 ################################################################################ |