Mercurial > traipse_dev
comparison orpg/networking/meta_server_lib.py @ 71:449a8900f9ac ornery-dev
Code refining almost completed, for this round. Some included files are still in need of some clean up, but this is test worthy.
author | sirebral |
---|---|
date | Thu, 20 Aug 2009 03:00:39 -0500 |
parents | c54768cffbd4 |
children | d1aff41c031b |
comparison
equal
deleted
inserted
replaced
70:52a5fa913008 | 71:449a8900f9ac |
---|---|
32 META_DEBUG = 0 | 32 META_DEBUG = 0 |
33 | 33 |
34 __version__ = "$Id: meta_server_lib.py,v 1.40 2007/04/04 01:18:42 digitalxero Exp $" | 34 __version__ = "$Id: meta_server_lib.py,v 1.40 2007/04/04 01:18:42 digitalxero Exp $" |
35 | 35 |
36 from orpg.orpg_version import PROTOCOL_VERSION | 36 from orpg.orpg_version import PROTOCOL_VERSION |
37 from orpg.orpgCore import * | 37 from orpg.orpgCore import component |
38 from orpg.tools.validate import validate | |
38 from orpg.dirpath import dir_struct | 39 from orpg.dirpath import dir_struct |
39 import urllib | 40 import urllib |
40 import orpg.minidom | 41 import orpg.minidom |
41 from threading import * | 42 from threading import * |
42 import time | 43 import time |
66 file.close() | 67 file.close() |
67 | 68 |
68 # Remove any leading or trailing data. This can happen on some satellite connections | 69 # Remove any leading or trailing data. This can happen on some satellite connections |
69 p = re.compile('(<servers>.*?</servers>)',re.DOTALL|re.IGNORECASE) | 70 p = re.compile('(<servers>.*?</servers>)',re.DOTALL|re.IGNORECASE) |
70 mo = p.search(data) | 71 mo = p.search(data) |
71 if mo: | 72 if mo: data = mo.group(0) |
72 data = mo.group(0) | |
73 | 73 |
74 if META_DEBUG: | 74 if META_DEBUG: |
75 print | 75 print |
76 print "Got this string from the Meta at " + path + ":" | 76 print "Got this string from the Meta at " + path + ":" |
77 print "===============================================" | 77 print "===============================================" |
82 xml_dom = xml.parseXml(data) | 82 xml_dom = xml.parseXml(data) |
83 xml_dom = xml_dom._get_documentElement() | 83 xml_dom = xml_dom._get_documentElement() |
84 return xml_dom | 84 return xml_dom |
85 | 85 |
86 def post_server_data( name, realHostName=None): | 86 def post_server_data( name, realHostName=None): |
87 # build POST data | |
88 ## data = urllib.urlencode( {"server_data[name]":name, | |
89 ## "server_data[version]":PROTOCOL_VERSION, | |
90 ## "act":"new"} ) | |
91 ## | |
92 if realHostName: | 87 if realHostName: |
93 data = urllib.urlencode( {"server_data[name]":name, | 88 data = urllib.urlencode( {"server_data[name]":name, |
94 "server_data[version]":PROTOCOL_VERSION, | 89 "server_data[version]":PROTOCOL_VERSION, |
95 "act":"new", | 90 "act":"new", |
96 "REMOTE_ADDR": realHostName } ) | 91 "REMOTE_ADDR": realHostName } ) |
99 #print "Letting meta server decide the hostname to list..." | 94 #print "Letting meta server decide the hostname to list..." |
100 data = urllib.urlencode( {"server_data[name]":name, | 95 data = urllib.urlencode( {"server_data[name]":name, |
101 "server_data[version]":PROTOCOL_VERSION, | 96 "server_data[version]":PROTOCOL_VERSION, |
102 "act":"new"} ) | 97 "act":"new"} ) |
103 | 98 |
104 xml_dom = get_server_dom( data , "http://openrpg.sf.net/openrpg_servers.php") | 99 #xml_dom = get_server_dom( data , "http://openrpg.sf.net/openrpg_servers.php")#Sourceforge still? |
100 path = component.get('settings').get_setting('MetaServerBaseURL') #getMetaServerBaseURL() | |
101 xml_dom = get_server_dom(data, path) | |
105 ret_val = int( xml_dom.getAttribute( "id" ) ) | 102 ret_val = int( xml_dom.getAttribute( "id" ) ) |
106 return ret_val | 103 return ret_val |
107 | 104 |
108 def post_failed_connection(id,meta=None,address=None,port=None): | 105 def post_failed_connection(id,meta=None,address=None,port=None): |
109 # For now, turning this off. This needs to be re-vamped for | 106 # For now, turning this off. This needs to be re-vamped for |
110 # handling multiple Metas. | 107 # handling multiple Metas. |
111 return 0 | 108 return 0 |
112 # data = urllib.urlencode({"id":id,"act":"failed"}); | 109 #data = urllib.urlencode({"id":id,"act":"failed"}); |
113 # xml_dom = get_server_dom(data) | 110 #xml_dom = get_server_dom(data) |
114 # ret_val = int(xml_dom.getAttribute("return")) | 111 #ret_val = int(xml_dom.getAttribute("return")) |
115 # return ret_val | 112 #return ret_val |
116 | 113 |
117 def remove_server(id): | 114 def remove_server(id): |
118 data = urllib.urlencode({"id":id,"act":"del"}); | 115 data = urllib.urlencode({"id":id,"act":"del"}); |
119 xml_dom = get_server_dom(data) | 116 xml_dom = get_server_dom(data) |
120 ret_val = int(xml_dom.getAttribute("return")) | 117 ret_val = int(xml_dom.getAttribute("return")) |
123 | 120 |
124 def byStartAttribute(first,second): | 121 def byStartAttribute(first,second): |
125 # This function is used to easily sort a list of nodes | 122 # This function is used to easily sort a list of nodes |
126 # by their start time | 123 # by their start time |
127 | 124 |
128 if first.hasAttribute("start"): | 125 if first.hasAttribute("start"): first_start = int(first.getAttribute("start")) |
129 first_start = int(first.getAttribute("start")) | 126 else: first_start = 0 |
130 else: | 127 |
131 first_start = 0 | 128 if second.hasAttribute("start"): second_start = int(second.getAttribute("start")) |
132 | 129 else: second_start = 0 |
133 if second.hasAttribute("start"): | |
134 second_start = int(second.getAttribute("start")) | |
135 else: | |
136 second_start = 0 | |
137 | 130 |
138 # Return the result of the cmp function on the two strings | 131 # Return the result of the cmp function on the two strings |
139 return cmp(first_start,second_start) | 132 return cmp(first_start,second_start) |
140 | 133 |
141 def byNameAttribute(first,second): | 134 def byNameAttribute(first,second): |
142 # This function is used to easily sort a list of nodes | 135 # This function is used to easily sort a list of nodes |
143 # by their name attribute | 136 # by their name attribute |
144 | 137 |
145 # Ensure there is something to sort with for each | 138 # Ensure there is something to sort with for each |
146 | 139 |
147 if first.hasAttribute("name"): | 140 if first.hasAttribute("name"): first_name = str(first.getAttribute("name")).lower() |
148 first_name = str(first.getAttribute("name")).lower() | 141 else: first_name = "" |
149 else: | 142 |
150 first_name = "" | 143 if second.hasAttribute("name"): second_name = str(second.getAttribute("name")).lower() |
151 | 144 else: second_name = "" |
152 if second.hasAttribute("name"): | |
153 second_name = str(second.getAttribute("name")).lower() | |
154 else: | |
155 second_name = "" | |
156 | 145 |
157 # Return the result of the cmp function on the two strings | 146 # Return the result of the cmp function on the two strings |
158 | |
159 return cmp(first_name,second_name) | 147 return cmp(first_name,second_name) |
160 | 148 |
161 | 149 |
162 def get_server_list(versions = None,sort_by="start"): | 150 def get_server_list(versions = None,sort_by="start"): |
163 data = urllib.urlencode({"version":PROTOCOL_VERSION,"ports":"%"}) | 151 data = urllib.urlencode({"version":PROTOCOL_VERSION,"ports":"%"}) |
169 | 157 |
170 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 |
171 | 159 |
172 for meta in all_metas: # check all of the metas | 160 for meta in all_metas: # check all of the metas |
173 | 161 |
174 # get the server's xml from the current meta | 162 #get the server's xml from the current meta |
175 bad_meta = 0 | 163 bad_meta = 0 |
176 #print "Getting server list from " + meta + "..." | 164 #print "Getting server list from " + meta + "..." |
177 try: | 165 try: xml_dom = get_server_dom(data=data,path=meta) |
178 xml_dom = get_server_dom(data=data,path=meta) | |
179 except: | 166 except: |
180 #print "Trouble getting servers from " + meta + "..." | 167 #print "Trouble getting servers from " + meta + "..." |
181 bad_meta = 1 | 168 bad_meta = 1 |
182 | 169 |
183 if bad_meta: | 170 if bad_meta: |
222 return_list = return_hash.values() | 209 return_list = return_hash.values() |
223 | 210 |
224 # sort them by their name attribute. Uses byNameAttribute() | 211 # sort them by their name attribute. Uses byNameAttribute() |
225 # defined above as a comparison function | 212 # defined above as a comparison function |
226 | 213 |
227 if sort_by == "start": | 214 if sort_by == "start": return_list.sort(byStartAttribute) |
228 return_list.sort(byStartAttribute) | 215 elif sort_by == "name": return_list.sort(byNameAttribute) |
229 elif sort_by == "name": | |
230 return_list.sort(byNameAttribute) | |
231 | 216 |
232 # Add each node to the DOM | 217 # Add each node to the DOM |
233 for n in return_list: | 218 for n in return_list: return_dom.appendChild(n) |
234 return_dom.appendChild(n) | |
235 return return_dom | 219 return return_dom |
236 | 220 |
237 ## List Format: | 221 ## List Format: |
238 ## <servers> | 222 ## <servers> |
239 ## <server address=? id=? name=? failed_count=? > | 223 ## <server address=? id=? name=? failed_count=? > |
267 def getRawMetaList(): | 251 def getRawMetaList(): |
268 try: | 252 try: |
269 try: | 253 try: |
270 metacache_lock.acquire() | 254 metacache_lock.acquire() |
271 # Read in the metas | 255 # Read in the metas |
272 component.get('validate').config_file("metaservers.cache","metaservers.cache") | 256 validate.config_file("metaservers.cache","metaservers.cache") |
273 ini = open(dir_struct["user"]+"metaservers.cache","r") | 257 ini = open(dir_struct["user"]+"metaservers.cache","r") |
274 metas = ini.readlines() | 258 metas = ini.readlines() |
275 ini.close() | 259 ini.close() |
276 return metas | 260 return metas |
277 finally: | 261 finally: |
280 if META_DEBUG: traceback.print_exc() | 264 if META_DEBUG: traceback.print_exc() |
281 print "Meta Server Lib: getRawMetaList(): " + str(e) | 265 print "Meta Server Lib: getRawMetaList(): " + str(e) |
282 return [] | 266 return [] |
283 | 267 |
284 def getMetaServers(versions = None, pick_random=0): | 268 def getMetaServers(versions = None, pick_random=0): |
285 # get meta server URLs as a list | 269 """ |
286 | 270 get meta server URLs as a list |
287 # versions is a list of acceptable version numbers. | 271 |
288 # A False truth value will use getMetaServerBaseURL() | 272 versions is a list of acceptable version numbers. |
289 | 273 A False truth value will use getMetaServerBaseURL() |
290 # set a default if we have weird reading problems | 274 |
291 # default_url = "http://www.openrpg.com/openrpg_servers.php" | 275 set a default if we have weird reading problems |
276 default_url = "http://www.openrpg.com/openrpg_servers.php" | |
277 """ | |
292 | 278 |
293 meta_names = [] | 279 meta_names = [] |
294 | 280 |
295 if(versions): # If versions are supplied, then look in metaservers.conf | 281 if(versions): # If versions are supplied, then look in metaservers.conf |
296 try: | 282 try: |
297 # read in the metas from file | 283 """ |
298 # format of file is one meta entry per line | 284 read in the metas from file |
299 # each entry will be the meta url, followed by one or more version numbers that it | 285 format of file is one meta entry per line |
300 # handle. Generally, this will be either a 1 for the original Meta format, or | 286 each entry will be the meta url, followed by one or more version numbers that it |
301 # 2 for the new one. | 287 handle. Generally, this will be either a 1 for the original Meta format, or |
288 2 for the new one. | |
289 """ | |
302 | 290 |
303 # Read in the metas | 291 # Read in the metas |
304 metas = getRawMetaList() | 292 metas = getRawMetaList() |
305 #print str(metas) | 293 #print str(metas) |
306 | 294 |
309 for meta in metas: | 297 for meta in metas: |
310 | 298 |
311 # split the line on whitespace | 299 # split the line on whitespace |
312 # obviously, your meta servers urls shouldn't contain whitespace. duh. | 300 # obviously, your meta servers urls shouldn't contain whitespace. duh. |
313 words = meta.split() | 301 words = meta.split() |
314 | |
315 success = 0 # init success flag for version check | 302 success = 0 # init success flag for version check |
316 | |
317 for version in versions: # run through each allowed version from caller | 303 for version in versions: # run through each allowed version from caller |
318 if version in words[1:]: # if the allowed version token was found | 304 if version in words[1:]: # if the allowed version token was found |
319 success += 1 # then increment the success indicator | 305 success += 1 # then increment the success indicator |
320 | |
321 if success: # if the meta entry is acceptable to the caller | 306 if success: # if the meta entry is acceptable to the caller |
322 meta_names.append(words[0]) # add the entry | 307 meta_names.append(words[0]) # add the entry |
323 if META_DEBUG: print "adding metaserver " + meta | 308 if META_DEBUG: print "adding metaserver " + meta |
324 | 309 |
325 # at this point, we should have at least one name from the cache. If not ... | 310 # at this point, we should have at least one name from the cache. If not ... |
326 if not meta_names: | 311 if not meta_names: |
327 default_meta = getMetaServerBaseURL() # grab the meta from ini.xml | 312 default_meta = getMetaServerBaseURL() # grab the meta from ini.xml |
328 meta_names.append(default_meta) # add it to the return list | 313 meta_names.append(default_meta) # add it to the return list |
329 # print "Warning!!\nNo valid metaservers cached." | 314 # print "Warning!!\nNo valid metaservers cached." |
330 # print "Using meta from MetaServerBaseURL: " + default_meta + "\n" | 315 # print "Using meta from MetaServerBaseURL: " + default_meta + "\n" |
331 # if we have more than one and want a random one | 316 # if we have more than one and want a random one |
332 elif pick_random: | 317 elif pick_random: |
333 if META_DEBUG: print "choosing random meta from: " + str(meta_names) | 318 if META_DEBUG: print "choosing random meta from: " + str(meta_names) |
334 i = int(random.uniform(0,len(meta_names))) | 319 i = int(random.uniform(0,len(meta_names))) |
335 #meta = meta_names[i] | 320 #meta = meta_names[i] |
362 node_list = tree.getElementsByTagName("MetaServerBaseURL") | 347 node_list = tree.getElementsByTagName("MetaServerBaseURL") |
363 if node_list: | 348 if node_list: |
364 url = node_list[0].getAttribute("value") | 349 url = node_list[0].getAttribute("value") |
365 | 350 |
366 # allow tree to be collected | 351 # allow tree to be collected |
367 try: | 352 try: tree.unlink() |
368 tree.unlink() | 353 except: pass |
369 except: | |
370 pass | |
371 | 354 |
372 except Exception,e: | 355 except Exception,e: |
373 print e | 356 print e |
374 # print "using meta server URI: " + url | 357 #print "using meta server URI: " + url |
375 return url | 358 return url |
376 | 359 |
377 ####################################################################################### | 360 """ |
378 # Beginning of Class registerThread | 361 Beginning of Class registerThread |
379 # | 362 |
380 # A Class to Manage Registration with the Meta2 | 363 A Class to Manage Registration with the Meta2 |
381 # Create an instance and call it's start() method | 364 Create an instance and call it's start() method |
382 # if you want to be (and stay) registered. This class | 365 if you want to be (and stay) registered. This class |
383 # will take care of registering and re-registering as | 366 will take care of registering and re-registering as |
384 # often as necessary to stay in the Meta list. | 367 often as necessary to stay in the Meta list. |
385 # | 368 |
386 # You may call register() yourself if you wish to change your | 369 You may call register() yourself if you wish to change your |
387 # server's name. It will immediately update the Meta. There | 370 server's name. It will immediately update the Meta. There |
388 # is no need to unregister first. | 371 is no need to unregister first. |
389 # | 372 |
390 # Call unregister() when you no longer want to be registered. | 373 Call unregister() when you no longer want to be registered. |
391 # This will result in the registerThread dying after | 374 This will result in the registerThread dying after |
392 # attempting to immediately remove itself from the Meta. | 375 attempting to immediately remove itself from the Meta. |
393 # | 376 |
394 # If you need to become registered again after that, you | 377 If you need to become registered again after that, you |
395 # must create a new instance of class registerThread. Don't | 378 must create a new instance of class registerThread. Don't |
396 # just try to call register() on the old, dead thread class. | 379 just try to call register() on the old, dead thread class. |
397 | 380 """ |
398 | 381 |
399 class registerThread(Thread): | 382 class registerThread(Thread): |
400 # Originally, I wrote this as a sub-class of wxThread, but | 383 """ |
401 # A) I couldn't get it to import right | 384 Originally, I wrote this as a sub-class of wxThread, but |
402 # B) I realized that I want this to be used in a server, | 385 A) I couldn't get it to import right |
403 # which I don't want needing wxWindows to run! | 386 B) I realized that I want this to be used in a server, |
404 # | 387 which I don't want needing wxWindows to run! |
405 # Because of this fact, there are some methods from wxThread | 388 |
406 # that I implemented to minimize changes to the code I had | 389 Because of this fact, there are some methods from wxThread |
407 # just written, i.e. TestDeleteStatus() and Delete() | 390 that I implemented to minimize changes to the code I had |
391 just written, i.e. TestDeleteStatus() and Delete() | |
392 """ | |
408 | 393 |
409 def __init__(self,name=None,realHostName=None,num_users = "Hmmm",MetaPath=None,port=6774,register_callback=None): | 394 def __init__(self,name=None,realHostName=None,num_users = "Hmmm",MetaPath=None,port=6774,register_callback=None): |
410 | 395 |
411 Thread.__init__(self,name="registerThread") | 396 Thread.__init__(self,name="registerThread") |
412 self.rlock = RLock() # Re-entrant lock used to make this class thread safe | 397 self.rlock = RLock() # Re-entrant lock used to make this class thread safe |
424 # indicates a new registration. | 409 # indicates a new registration. |
425 self.interval = 0 # interval returned from Meta. Is how often to | 410 self.interval = 0 # interval returned from Meta. Is how often to |
426 # re-register, in minutes. | 411 # re-register, in minutes. |
427 self.destroy = 0 # Used to flag that this thread should die | 412 self.destroy = 0 # Used to flag that this thread should die |
428 self.port = str(port) | 413 self.port = str(port) |
429 self.register_callback = register_callback # set a method to call to report result of register | 414 self.register_callback = register_callback # set a method to call to report result of register |
430 # This thread will communicate with one and only one | 415 """ |
431 # Meta. If the Meta in ini.xml is changed after | 416 This thread will communicate with one and only one |
432 # instantiation, then this instance must be | 417 Meta. If the Meta in ini.xml is changed after |
433 # unregistered and a new instance instantiated. | 418 instantiation, then this instance must be |
434 # | 419 unregistered and a new instance instantiated. |
435 # Also, if MetaPath is specified, then use that. Makes | 420 |
436 # it easier to have multiple registerThreads going to keep the server registered | 421 Also, if MetaPath is specified, then use that. Makes |
437 # on multiple (compatible) Metas. | 422 it easier to have multiple registerThreads going to keep the server registered |
423 on multiple (compatible) Metas. | |
424 """ | |
438 | 425 |
439 if MetaPath == None: | 426 if MetaPath == None: |
440 self.path = getMetaServerBaseURL() # Do this if no Meta specified | 427 self.path = getMetaServerBaseURL() # Do this if no Meta specified |
441 else: | 428 else: |
442 self.path = MetaPath | 429 self.path = MetaPath |
457 self.die_event.set() | 444 self.die_event.set() |
458 finally: | 445 finally: |
459 self.rlock.release() | 446 self.rlock.release() |
460 | 447 |
461 def run(self): | 448 def run(self): |
462 # This method gets called by Thread implementation | 449 """ |
463 # when self.start() is called to begin the thread's | 450 This method gets called by Thread implementation |
464 # execution | 451 when self.start() is called to begin the thread's |
465 # | 452 execution |
466 # We will basically enter a loop that continually | 453 |
467 # re-registers this server and sleeps Interval | 454 We will basically enter a loop that continually |
468 # minutes until the thread is ordered to die in place | 455 re-registers this server and sleeps Interval |
456 minutes until the thread is ordered to die in place | |
457 """ | |
469 while(not self.TestDeleteStatus()): # Loop while until told to die | 458 while(not self.TestDeleteStatus()): # Loop while until told to die |
470 # Otherwise, call thread safe register(). | 459 # Otherwise, call thread safe register(). |
471 self.register(self.name, self.realHostName, self.num_users) | 460 self.register(self.name, self.realHostName, self.num_users) |
472 if META_DEBUG: print "Sent Registration Data" | 461 if META_DEBUG: print "Sent Registration Data" |
473 | |
474 # register() will end up setting the state variables | 462 # register() will end up setting the state variables |
475 # for us, including self.interval. | 463 # for us, including self.interval. |
476 try: | 464 try: |
477 self.rlock.acquire() # Serialize access to this state information | 465 self.rlock.acquire() # Serialize access to this state information |
478 | 466 |
491 # If we get past the while loop, it's because we've been asked to die, | 479 # If we get past the while loop, it's because we've been asked to die, |
492 # so just let run() end. Once this occurs, the thread is dead and | 480 # so just let run() end. Once this occurs, the thread is dead and |
493 # calls to Thread.isAlive() return False. | 481 # calls to Thread.isAlive() return False. |
494 | 482 |
495 def unregister(self): | 483 def unregister(self): |
496 # This method can (I hope) be called from both within the thread | 484 """ |
497 # and from other threads. It will attempt to unregister this | 485 This method can (I hope) be called from both within the thread |
498 # server from the Meta database | 486 and from other threads. It will attempt to unregister this |
499 # When this is either accomplished or has been tried hard enough | 487 server from the Meta database |
500 # (after which it just makes sense to let the Meta remove the | 488 When this is either accomplished or has been tried hard enough |
501 # entry itself when we don't re-register using this id), | 489 (after which it just makes sense to let the Meta remove the |
502 # this method will either cause the thread to immediately die | 490 entry itself when we don't re-register using this id), |
503 # (if called from this thread's context) or set the Destroy flag | 491 this method will either cause the thread to immediately die |
504 # (if called from the main thread), a positive test for which will cause | 492 (if called from this thread's context) or set the Destroy flag |
505 # the code in Entry() to exit() when the thread wakes up and | 493 (if called from the main thread), a positive test for which will cause |
506 # checks TestDeleteStatus(). | 494 the code in Entry() to exit() when the thread wakes up and |
507 # lock the critical section. The unlock will | 495 checks TestDeleteStatus(). |
508 # automatically occur at the end of the function in the finally clause | 496 lock the critical section. The unlock will |
497 automatically occur at the end of the function in the finally clause | |
498 """ | |
509 try: | 499 try: |
510 self.rlock.acquire() | 500 self.rlock.acquire() |
511 if not self.isAlive(): # check to see if this thread is dead | 501 if not self.isAlive(): # check to see if this thread is dead |
512 return 1 # If so, return an error result | 502 return 1 # If so, return an error result |
513 # Do the actual unregistering here | 503 # Do the actual unregistering here |
526 # No special handling is required. If the de-registration worked we're done. If | 516 # No special handling is required. If the de-registration worked we're done. If |
527 # not, then it's because we've already been removed or have a bad cookie. Either | 517 # not, then it's because we've already been removed or have a bad cookie. Either |
528 # way, we can't do anything else, so die. | 518 # way, we can't do anything else, so die. |
529 self.Delete() # This will cause the registerThread to die in register() | 519 self.Delete() # This will cause the registerThread to die in register() |
530 # prep xml_dom for garbage collection | 520 # prep xml_dom for garbage collection |
531 try: | 521 try: xml_dom.unlink() |
532 xml_dom.unlink() | 522 except: pass |
533 except: | |
534 pass | |
535 return 0 | 523 return 0 |
536 finally: | 524 finally: self.rlock.release() |
537 self.rlock.release() | |
538 | 525 |
539 def register(self, name=None, realHostName=None, num_users=None): | 526 def register(self, name=None, realHostName=None, num_users=None): |
540 # Designed to handle the registration, both new and | 527 """ |
541 # repeated. | 528 Designed to handle the registration, both new and |
542 # | 529 repeated. |
543 # It is intended to be called once every interval | 530 |
544 # (or interval - delta) minutes. | 531 It is intended to be called once every interval |
545 | 532 (or interval - delta) minutes. |
546 # lock the critical section. The unlock will | 533 |
547 # automatically occur at the end of the function in the finally clause | 534 lock the critical section. The unlock will |
535 automatically occur at the end of the function in the finally clause | |
536 """ | |
548 try: | 537 try: |
549 self.rlock.acquire() | 538 self.rlock.acquire() |
550 if not self.isAlive(): # check to see if this thread is dead | 539 if not self.isAlive(): # check to see if this thread is dead |
551 return 1 # If so, return an error result | 540 return 1 # If so, return an error result |
552 | 541 |
553 # Set the server's attibutes, if specified. | 542 # Set the server's attibutes, if specified. |
554 if name: | 543 if name: self.name = name |
555 self.name = name | 544 if num_users != None: self.num_users = num_users |
556 if num_users != None: | 545 if realHostName: self.realHostName = realHostName |
557 self.num_users = num_users | |
558 if realHostName: | |
559 self.realHostName = realHostName | |
560 # build POST data | 546 # build POST data |
561 if self.realHostName: | 547 if self.realHostName: |
562 data = urllib.urlencode( {"server_data[id]":self.id, | 548 data = urllib.urlencode( {"server_data[id]":self.id, |
563 "server_data[cookie]":self.cookie, | 549 "server_data[cookie]":self.cookie, |
564 "server_data[name]":self.name, | 550 "server_data[name]":self.name, |
581 except: | 567 except: |
582 if META_DEBUG: print "Problem talking to server. Setting interval for retry ..." | 568 if META_DEBUG: print "Problem talking to server. Setting interval for retry ..." |
583 if META_DEBUG: print data | 569 if META_DEBUG: print data |
584 if META_DEBUG: print | 570 if META_DEBUG: print |
585 self.interval = 0 | 571 self.interval = 0 |
586 # If we are in the registerThread thread, then setting interval to 0 | 572 """ |
587 # will end up causing a retry in about 6 seconds (see self.run()) | 573 If we are in the registerThread thread, then setting interval to 0 |
588 # If we are in the main thread, then setting interval to 0 will do one | 574 will end up causing a retry in about 6 seconds (see self.run()) |
589 # of two things: | 575 If we are in the main thread, then setting interval to 0 will do one |
590 # 1) Do the same as if we were in the registerThread | 576 of two things: |
591 # 2) Cause the next, normally scheduled register() call to use the values | 577 1) Do the same as if we were in the registerThread |
592 # provided in this call. | 578 2) Cause the next, normally scheduled register() call to use the values |
593 # | 579 provided in this call. |
594 # Which case occurs depends on where the registerThread thread is when | 580 |
595 # the main thread calls register(). | 581 Which case occurs depends on where the registerThread thread is when |
582 the main thread calls register(). | |
583 """ | |
596 return 0 # indicates that it was okay to call, not that no errors occurred | 584 return 0 # indicates that it was okay to call, not that no errors occurred |
585 | |
597 # If there is a DOM returned .... | 586 # If there is a DOM returned .... |
598 if xml_dom: | 587 if xml_dom: |
599 # If there's an error, echo it to the console | 588 # If there's an error, echo it to the console |
600 if xml_dom.hasAttribute("errmsg"): | 589 if xml_dom.hasAttribute("errmsg"): |
601 print "Error durring registration: " + xml_dom.getAttribute("errmsg") | 590 print "Error durring registration: " + xml_dom.getAttribute("errmsg") |
602 if META_DEBUG: print data | 591 if META_DEBUG: print data |
603 if META_DEBUG: print | 592 if META_DEBUG: print |
604 # No special handling is required. If the registration worked, id, cookie, and interval | 593 """ |
605 # can be stored and used for the next time. | 594 No special handling is required. If the registration worked, id, cookie, and interval |
606 # If an error occurred, then the Meta will delete us and we need to re-register as | 595 can be stored and used for the next time. |
607 # a new server. The way to indicate this is with a "0" id and "0" cookie sent to | 596 If an error occurred, then the Meta will delete us and we need to re-register as |
608 # the server during the next registration. Since that's what the server returns to | 597 a new server. The way to indicate this is with a "0" id and "0" cookie sent to |
609 # us on an error anyway, we just store them and the next registration will | 598 the server during the next registration. Since that's what the server returns to |
610 # automatically be set up as a new one. | 599 us on an error anyway, we just store them and the next registration will |
611 # | 600 automatically be set up as a new one. |
612 # Unless the server calls register() itself in the meantime. Of course, that's okay | 601 |
613 # too, because a success on THAT register() call will set up the next one to use | 602 Unless the server calls register() itself in the meantime. Of course, that's okay |
614 # the issued id and cookie. | 603 too, because a success on THAT register() call will set up the next one to use |
615 # | 604 the issued id and cookie. |
616 # The interval is stored unconditionally for similar reasons. If there's an error, | 605 |
617 # the interval will be less than 1, and the main thread's while loop will reset it | 606 The interval is stored unconditionally for similar reasons. If there's an error, |
618 # to 6 seconds for the next retry. | 607 the interval will be less than 1, and the main thread's while loop will reset it |
619 # Is it wrong to have a method where there's more comments than code? :) | 608 to 6 seconds for the next retry. |
609 Is it wrong to have a method where there's more comments than code? :) | |
610 """ | |
620 try: | 611 try: |
621 self.interval = int(xml_dom.getAttribute("interval")) | 612 self.interval = int(xml_dom.getAttribute("interval")) |
622 self.id = xml_dom.getAttribute("id") | 613 self.id = xml_dom.getAttribute("id") |
623 self.cookie = xml_dom.getAttribute("cookie") | 614 self.cookie = xml_dom.getAttribute("cookie") |
624 if not xml_dom.hasAttribute("errmsg"): | 615 if not xml_dom.hasAttribute("errmsg"): |