Changeset 570:7b92e7021a5b
- Timestamp:
- 10/05/14 12:30:27 (10 years ago)
- Branch:
- default
- Phase:
- public
- Location:
- src/mlx
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/mlx/gui/flight.py
r564 r570 1989 1989 s = "" 1990 1990 for notam in notams: 1991 s += str(notam.begin) 1992 if notam.end is not None: 1993 s += " - " + str(notam.end) 1994 elif notam.permanent: 1995 s += " - PERMANENT" 1996 s += "\n" 1997 if notam.repeatCycle: 1998 s += "Repeat cycle: " + notam.repeatCycle + "\n" 1999 s += notam.notice + "\n" 1991 s += str(notam) 2000 1992 s += "-------------------- * --------------------\n" 2001 1993 buffer.set_text(s) -
src/mlx/web.py
r496 r570 14 14 import xml.sax 15 15 import xmlrpclib 16 import HTMLParser 16 17 17 18 #--------------------------------------------------------------------------------------- … … 353 354 class NOTAM(object): 354 355 """A NOTAM for an airport.""" 355 def __init__(self, begin, notice, end = None, permanent = False, 356 def __init__(self, ident, basic, 357 begin, notice, end = None, permanent = False, 356 358 repeatCycle = None): 357 359 """Construct the NOTAM.""" 360 self.ident = ident 361 self.basic = basic 358 362 self.begin = begin 359 363 self.notice = notice 360 364 self.end = end 361 365 self.permanent = permanent 362 self.repeatCycle = None366 self.repeatCycle = repeatCycle 363 367 364 368 def __repr__(self): … … 375 379 return s 376 380 381 def __str__(self): 382 """Get the string representation of the NOTAM.""" 383 s = "" 384 s += str(self.ident) + " " + str(self.basic) + "\n" 385 s += str(self.begin) 386 if self.end is not None: 387 s += " - " + str(self.end) 388 elif self.permanent: 389 s += " - PERMANENT" 390 s += "\n" 391 if self.repeatCycle: 392 s += "Repeat cycle: " + self.repeatCycle + "\n" 393 s += self.notice + "\n" 394 return s 395 377 396 #------------------------------------------------------------------------------ 378 397 … … 388 407 """Start an element.""" 389 408 if name!="notam" or \ 409 "ident" not in attrs or not attrs["ident"] or \ 410 "Q" not in attrs or not attrs["Q"] or \ 390 411 "A" not in attrs or not attrs["A"] or \ 391 412 "B" not in attrs or not attrs["B"] or \ … … 406 427 repeatCycle = attrs["D"] if "D" in attrs else None 407 428 408 self._notams[icao].append(NOTAM(begin, attrs["E"], end = end, 429 self._notams[icao].append(NOTAM(attrs["ident"], attrs["Q"], 430 begin, attrs["E"], end = end, 409 431 permanent = permanent, 410 432 repeatCycle = repeatCycle)) … … 413 435 """Get the NOTAMs for the given ICAO code.""" 414 436 return self._notams[icao] if icao in self._notams else [] 437 438 #------------------------------------------------------------------------------ 439 440 class PilotsWebNOTAMsParser(HTMLParser.HTMLParser): 441 """XML handler for the NOTAM query results on the PilotsWeb website.""" 442 def __init__(self): 443 """Construct the handler.""" 444 HTMLParser.HTMLParser.__init__(self) 445 446 self._notams = [] 447 self._currentNOTAM = "" 448 self._stage = 0 449 450 def handle_starttag(self, name, attrs): 451 """Start an element.""" 452 if (self._stage==0 and name=="div" and ("id", "notamRight") in attrs) or \ 453 (self._stage==1 and name=="span") or \ 454 (self._stage==2 and name=="pre"): 455 self._stage += 1 456 if self._stage==1: 457 self._currentNOTAM = "" 458 459 def handle_data(self, content): 460 """Handle characters""" 461 if self._stage==3: 462 self._currentNOTAM += content 463 464 def handle_endtag(self, name): 465 """End an element.""" 466 if (self._stage==3 and name=="pre") or \ 467 (self._stage==2 and name=="span") or \ 468 (self._stage==1 and name=="div"): 469 self._stage -= 1 470 if self._stage==0: 471 self._processCurrentNOTAM() 472 473 def getNOTAMs(self): 474 """Get the NOTAMs collected""" 475 return self._notams 476 477 def _processCurrentNOTAM(self): 478 """Parse the current NOTAM and append its contents to the list of 479 NOTAMS.""" 480 notam = None 481 try: 482 notam = self._parseCurrentNOTAM2() 483 except Exception, e: 484 print "Error parsing current NOTAM: " + str(e) 485 486 if notam is None: 487 print "Could not parse NOTAM: " + self._currentNOTAM 488 if self._currentNOTAM: 489 self._notams.append(self._currentNOTAM + "\n") 490 else: 491 self._notams.append(notam) 492 493 def _parseCurrentNOTAM(self): 494 """Parse the current NOTAM, if possible, and return a NOTAM object.""" 495 lines = self._currentNOTAM.splitlines() 496 lines = map(lambda line: line.strip(), lines) 497 498 if len(lines)<4: 499 return None 500 501 if not lines[1].startswith("Q)") or \ 502 not lines[2].startswith("A)") or \ 503 not (lines[3].startswith("E)") or 504 (lines[3].startswith("D)") and lines[4].startswith("E)"))): 505 return None 506 507 ident = lines[0].split()[0] 508 basic = lines[1][2:].strip() 509 510 words = lines[2].split() 511 if len(words)<4 or words[0]!="A)" or words[2]!="B)": 512 return None 513 514 begin = datetime.datetime.strptime(words[3], "%y%m%d%H%M") 515 end = None 516 permanent = False 517 if words[4]=="C)" and len(words)>=6: 518 if words[5] in ["PERM", "UFN"]: 519 permanent = True 520 else: 521 end = datetime.datetime.strptime(words[5], "%y%m%d%H%M") 522 else: 523 permanent = True 524 525 repeatCycle = None 526 noticeStartIndex = 3 527 if lines[3].startswith("D)"): 528 repeatCycle = lines[3][2:].strip() 529 noticeStartIndex = 4 530 531 notice = "" 532 for index in range(noticeStartIndex, len(lines)): 533 line = lines[index][2:] if index==noticeStartIndex else lines[index] 534 line = line.strip() 535 536 if line.lower().startswith("created:") or \ 537 line.lower().startswith("source:"): 538 break 539 540 if notice: notice += " " 541 notice += line 542 543 return NOTAM(ident, basic, begin, notice, end = end, 544 permanent = permanent, repeatCycle = repeatCycle) 545 546 def _parseCurrentNOTAM2(self): 547 """Parse the current NOTAM with a second, more flexible method.""" 548 lines = self._currentNOTAM.splitlines() 549 lines = map(lambda line: line.strip(), lines) 550 551 if not lines: 552 return None 553 554 ident = lines[0].split()[0] 555 556 lines = lines[1:] 557 for i in range(0, 2): 558 l = lines[-1].lower() 559 if l.startswith("created:") or l.startswith("source:"): 560 lines = lines[:-1] 561 562 lines = map(lambda line: line.strip(), lines) 563 contents = " ".join(lines).split() 564 565 items = {} 566 for i in ["Q)", "A)", "B)", "C)", "D)", "E)"]: 567 items[i] = "" 568 569 currentItem = None 570 for word in contents: 571 if word in items: 572 currentItem = word 573 elif currentItem in items: 574 s = items[currentItem] 575 if s: s+= " " 576 s += word 577 items[currentItem] = s 578 579 if not items["Q)"] or not items["A)"] or not items["B)"] or \ 580 not items["E)"]: 581 return None 582 583 basic = items["Q)"] 584 begin = datetime.datetime.strptime(items["B)"], "%y%m%d%H%M") 585 586 end = None 587 permanent = False 588 if items["C)"]: 589 endItem = items["C)"] 590 if endItem in ["PERM", "UFN"]: 591 permanent = True 592 else: 593 end = datetime.datetime.strptime(items["C)"], "%y%m%d%H%M") 594 else: 595 permanent = True 596 597 repeatCycle = None 598 if items["D)"]: 599 repeatCycle = items["D)"] 600 601 notice = items["E)"] 602 603 return NOTAM(ident, basic, begin, notice, end = end, 604 permanent = permanent, repeatCycle = repeatCycle) 415 605 416 606 #------------------------------------------------------------------------------ … … 469 659 except Exception, e: 470 660 print >> sys.stderr, "web.Handler.Request.perform: callback throwed an exception: " + util.utf2unicode(str(e)) 471 traceback.print_exc()661 #traceback.print_exc() 472 662 473 663 #------------------------------------------------------------------------------ … … 610 800 def run(self): 611 801 """Perform the retrieval of the NOTAMs.""" 612 xmlParser = xml.sax.make_parser() 613 notamHandler = NOTAMHandler([self._departureICAO, self._arrivalICAO]) 614 xmlParser.setContentHandler(notamHandler) 615 616 url = "http://notams.euroutepro.com/notams.xml" 617 618 f = urllib2.urlopen(url, timeout = 10.0) 802 departureNOTAMs = self.getPilotsWebNOTAMs(self._departureICAO) 803 arrivalNOTAMs = self.getPilotsWebNOTAMs(self._arrivalICAO) 804 805 icaos = [] 806 if not departureNOTAMs: icaos.append(self._departureICAO) 807 if not arrivalNOTAMs: icaos.append(self._arrivalICAO) 808 809 if icaos: 810 xmlParser = xml.sax.make_parser() 811 notamHandler = NOTAMHandler(icaos) 812 xmlParser.setContentHandler(notamHandler) 813 814 url = "http://notams.euroutepro.com/notams.xml" 815 816 f = urllib2.urlopen(url, timeout = 10.0) 817 try: 818 xmlParser.parse(f) 819 finally: 820 f.close() 821 822 for icao in icaos: 823 if icao==self._departureICAO: 824 departureNOTAMs = notamHandler.get(icao) 825 else: 826 arrivalNOTAMs = notamHandler.get(icao) 827 828 result = Result() 829 result.departureNOTAMs = departureNOTAMs 830 result.arrivalNOTAMs = arrivalNOTAMs 831 832 return result 833 834 def getPilotsWebNOTAMs(self, icao): 835 """Try to get the NOTAMs from FAA's PilotsWeb site for the given ICAO 836 code. 837 838 Returns a list of PilotsWEBNOTAM objects, or None in case of an error.""" 619 839 try: 620 xmlParser.parse(f) 621 finally: 622 f.close() 623 624 result = Result() 625 result.departureNOTAMs = notamHandler.get(self._departureICAO) 626 result.arrivalNOTAMs = notamHandler.get(self._arrivalICAO) 627 628 return result 840 parser = PilotsWebNOTAMsParser() 841 842 url = "https://pilotweb.nas.faa.gov/PilotWeb/notamRetrievalByICAOAction.do?method=displayByICAOs&formatType=ICAO&retrieveLocId=%s&reportType=RAW&actionType=notamRetrievalByICAOs" % \ 843 (icao.upper(),) 844 845 f = urllib2.urlopen(url, timeout = 10.0) 846 try: 847 data = f.read(16384) 848 while data: 849 parser.feed(data) 850 data = f.read(16384) 851 finally: 852 f.close() 853 854 return parser.getNOTAMs() 855 856 except Exception, e: 857 traceback.print_exc() 858 print "mlx.web.GetNOTAMs.getPilotsWebNOTAMs: failed to get NOTAMs for '%s': %s" % \ 859 (icao, str(e)) 860 return None 629 861 630 862 #------------------------------------------------------------------------------
Note:
See TracChangeset
for help on using the changeset viewer.