Changeset 859:1e789c934953
- Timestamp:
- 06/18/17 11:17:51 (7 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
locale/en/mlx.po
r858 r859 138 138 msgid "button_save" 139 139 msgstr "_Save" 140 141 msgid "button_book" 142 msgstr "_Book" 143 144 msgid "button_close" 145 msgstr "_Close" 140 146 141 147 msgid "menu_file" … … 2669 2675 msgstr "Filtering criteria" 2670 2676 2677 msgid "timetable_popup_book" 2678 msgstr "_Book" 2679 2680 msgid "timetable_book_title" 2681 msgstr "Book flight" 2682 2683 msgid "timetable_book_frame_title" 2684 msgstr "Flight details" 2685 2686 msgid "timetable_book_callsign" 2687 msgstr "<b>Flight number</b>:" 2688 2689 msgid "timetable_book_from_to" 2690 msgstr "<b>From - to</b>:" 2691 2692 msgid "timetable_book_flightDate" 2693 msgstr "<b>Flight date</b>:" 2694 2695 msgid "timetable_book_flightDate_tooltip" 2696 msgstr "You can select a different date for your flight." 2697 2698 msgid "timetable_book_dep_arr" 2699 msgstr "<b>Departure - arrival</b>:" 2700 2701 msgid "timetable_book_duration" 2702 msgstr "<b>Duration</b>:" 2703 2704 msgid "timetable_book_tailNumber" 2705 msgstr "<b>Tail number</b>:" 2706 2707 msgid "timetable_book_tailNumber_tooltip" 2708 msgstr "" 2709 "Select the tail number of aircraft which " 2710 "you would like to perform the flight with" 2711 2712 msgid "bookflights_busy" 2713 msgstr "Booking flights..." 2714 2715 msgid "bookflights_successful" 2716 msgstr "The booking is successful." 2717 2718 msgid "bookflights_successful_secondary" 2719 msgstr "Have a nice flight!" 2720 2721 msgid "bookflights_failed" 2722 msgstr "Failed to book flights." 2723 2724 msgid "bookflights_failed_secondary" 2725 msgstr "" 2726 "The MAVA server may not work temporarily. " 2727 "Retry the booking some time later. " 2728 "If the problem persists, report a bug." 2729 2671 2730 msgid "error_communication" 2672 2731 msgstr "Communication error" -
locale/hu/mlx.po
r858 r859 138 138 msgid "button_save" 139 139 msgstr "_Mentés" 140 141 msgid "button_book" 142 msgstr "_Foglalás" 143 144 msgid "button_close" 145 msgstr "_Bezár" 140 146 141 147 msgid "menu_file" … … 2686 2692 msgstr "Szűrési feltételek" 2687 2693 2694 msgid "timetable_popup_book" 2695 msgstr "_Fogalás" 2696 2697 msgid "timetable_book_title" 2698 msgstr "Járat lefoglalása" 2699 2700 msgid "timetable_book_frame_title" 2701 msgstr "A járat részletei" 2702 2703 msgid "timetable_book_callsign" 2704 msgstr "<b>Járatszám</b>:" 2705 2706 msgid "timetable_book_flightDate" 2707 msgstr "<b>Dátum</b>:" 2708 2709 msgid "timetable_book_flightDate_tooltip" 2710 msgstr "A megadottól eltérő dátumot is választhatsz." 2711 2712 msgid "timetable_book_from_to" 2713 msgstr "<b>Honnan - hová</b>:" 2714 2715 msgid "timetable_book_dep_arr" 2716 msgstr "<b>Érkezés - indulás</b>:" 2717 2718 msgid "timetable_book_duration" 2719 msgstr "<b>Duration</b>:" 2720 2721 msgid "timetable_book_tailNumber" 2722 msgstr "<b>Lajstromjel</b>:" 2723 2724 msgid "timetable_book_tailNumber_tooltip" 2725 msgstr "" 2726 "Válaszd ki annak a gépnek a lajstromjelét, " 2727 "amelyikkel teljesíteni szeretnéd a járatot." 2728 2729 msgid "bookflights_busy" 2730 msgstr "Járat foglalása..." 2731 2732 msgid "bookflights_successful" 2733 msgstr "A foglalás sikerült." 2734 2735 msgid "bookflights_successful_secondary" 2736 msgstr "Jó repülést!" 2737 2738 msgid "bookflights_failed" 2739 msgstr "Nem sikerült lefoglalni a járatot." 2740 2741 msgid "bookflights_failed_secondary" 2742 msgstr "" 2743 "Lehet, hogy a MAVA szerver átmenetileg nem működik. " 2744 "Próbáld meg később a foglalást. " 2745 "Ha a hiba továbbra is fennáll, jelents be." 2746 2688 2747 msgid "error_communication" 2689 2748 msgstr "Kommunikációs hiba" -
src/mlx/const.py
r858 r859 1 1 2 2 import sys 3 import datetime 3 4 4 5 #------------------------------------------------------------------------------- … … 559 560 560 561 #------------------------------------------------------------------------------- 562 563 defaultDate = datetime.date(1900, 1, 1) 564 565 #------------------------------------------------------------------------------- -
src/mlx/gui/flight.py
r854 r859 528 528 if self._wizard.loggedIn: 529 529 for flight in loginResult.flights: 530 self. _addFlight(flight)530 self.addFlight(flight) 531 531 for flight in loginResult.reportedFlights: 532 532 self._pendingFlightsWindow.addReportedFlight(flight) … … 536 536 self._updatePendingButton() 537 537 538 def _addFlight(self, flight):538 def addFlight(self, flight): 539 539 """Add the given file to the list of flights.""" 540 540 self._flights.append(flight) … … 543 543 def _reflyFlight(self, flight): 544 544 """Refly the given flight.""" 545 self. _addFlight(flight)545 self.addFlight(flight) 546 546 self._updatePending() 547 547 … … 641 641 with open(fileName, "rt") as f: 642 642 bookedFlight.readFromFile(f) 643 self. _addFlight(bookedFlight)643 self.addFlight(bookedFlight) 644 644 except Exception, e: 645 645 print "Failed to load flight:", util.utf2unicode(str(e)) … … 5479 5479 """Reload the flights from the MAVA server.""" 5480 5480 self.login(callback, None, None) 5481 5482 def addFlight(self, bookedFlight): 5483 """Add the given booked flight to the flight selection page.""" 5484 self._flightSelectionPage.addFlight(bookedFlight) 5481 5485 5482 5486 def reflyFlight(self, bookedFlight): -
src/mlx/gui/flightlist.py
r858 r859 28 28 self._defaultDescending = defaultDescending 29 29 self._cellDataFn = cellDataFn 30 31 @property 32 def attribute(self): 33 """Get the attribute the column belongs to.""" 34 return self._attribute 30 35 31 36 @property -
src/mlx/gui/gui.py
r858 r859 97 97 self._credentialsPassword = None 98 98 99 self._bookFlightsUserCallback = None 100 self._bookFlightsBusyCallback = None 101 99 102 self.webHandler = web.Handler(config, self._getCredentialsCallback) 100 103 self.webHandler.start() … … 557 560 self._flightInfo.enable(aircraftType) 558 561 562 def bookFlights(self, callback, flightIDs, date, tailNumber, 563 busyCallback = None): 564 """Initiate the booking of flights with the given timetable IDs and 565 other data""" 566 self._bookFlightsUserCallback = callback 567 self._bookFlightsBusyCallback = busyCallback 568 569 self.beginBusy(xstr("bookflights_busy")) 570 if busyCallback is not None: 571 busyCallback(True) 572 573 self.webHandler.bookFlights(self._bookFlightsCallback, 574 flightIDs, date, tailNumber) 575 576 def _bookFlightsCallback(self, returned, result): 577 """Called when the booking of flights has finished.""" 578 gobject.idle_add(self._handleBookFlightsResult, returned, result) 579 580 def _handleBookFlightsResult(self, returned, result): 581 """Called when the booking of flights is done. 582 583 If it was successful, the booked flights are added to the list of the 584 flight selector.""" 585 if self._bookFlightsBusyCallback is not None: 586 self._bookFlightsBusyCallback(False) 587 self.endBusy() 588 589 if returned: 590 for bookedFlight in result.bookedFlights: 591 self._wizard.addFlight(bookedFlight) 592 593 self._bookFlightsUserCallback(returned, result) 594 559 595 def cancelFlight(self): 560 596 """Cancel the current file, if the user confirms it.""" … … 853 889 gobject.idle_add(self.getFleet, callback, force) 854 890 855 def getFleet(self, callback = None, force = False ):891 def getFleet(self, callback = None, force = False, busyCallback = None): 856 892 """Get the fleet. 857 893 … … 860 896 if self._fleet is None or force: 861 897 self._fleetCallback = callback 898 self._fleetBusyCallback = busyCallback 899 if busyCallback is not None: 900 busyCallback(True) 862 901 self.beginBusy(xstr("fleet_busy")) 863 902 self.webHandler.getFleet(self._fleetResultCallback) … … 896 935 """Handle the fleet result.""" 897 936 self.endBusy() 937 if self._fleetBusyCallback is not None: 938 self._fleetBusyCallback(False) 898 939 if returned: 899 940 self._fleet = result.fleet … … 911 952 callback = self._fleetCallback 912 953 self._fleetCallback = None 954 self._fleetBusyCallback = None 913 955 if callback is not None: 914 956 callback(self._fleet) -
src/mlx/gui/timetable.py
r858 r859 5 5 from mlx.gui.common import * 6 6 from flightlist import ColumnDescriptor 7 from mlx.rpc import ScheduledFlight 7 8 8 9 import mlx.const as const 9 10 10 11 import datetime 12 import random 11 13 12 14 #----------------------------------------------------------------------------- … … 38 40 "%02d:%02d" % (duration/3600, 39 41 (duration%3600)/60)), 40 ColumnDescriptor(" spec", xstr("timetable_vip"), type = bool,42 ColumnDescriptor("type", xstr("timetable_vip"), type = bool, 41 43 renderer = _getVIPRenderer(), 42 44 sortable = True, 43 convertFn = lambda spec, flight: spec==1) 45 convertFn = lambda type, flight: 46 type==ScheduledFlight.TYPE_VIP) 44 47 ] 48 49 columnOrdering = ["callsign", "aircraftType", 50 "date", "departureTime", "arrivalTime", 51 "departureICAO", "arrivalICAO", "duration", "type"] 45 52 46 53 @staticmethod … … 48 55 """Determine if the given flight is selected by the given 49 56 filtering conditions.""" 50 return ((regularEnabled and flight. spec==0) or \51 (vipEnabled and flight. spec==1)) and \57 return ((regularEnabled and flight.type==ScheduledFlight.TYPE_NORMAL) or \ 58 (vipEnabled and flight.type==ScheduledFlight.TYPE_VIP)) and \ 52 59 flight.aircraftType in aircraftTypes 53 60 … … 75 82 self._view = gtk.TreeView(self._model) 76 83 84 self._tooltips = gtk.Tooltips() 85 self._tooltips.disable() 86 self._view.connect("motion-notify-event", self._updateTooltip) 87 77 88 flightPairIndexColumn = gtk.TreeViewColumn() 78 89 flightPairIndexColumn.set_visible(False) … … 83 94 column = columnDescriptor.getViewColumn(index) 84 95 self._view.append_column(column) 96 self._model.set_sort_func(index, self._compareFlights, 97 columnDescriptor.attribute) 85 98 index += 1 86 99 … … 110 123 111 124 @property 125 def selectedIndexes(self): 126 """Get the indexes of the selected entries, if any. 127 128 The indexes are sorted.""" 129 selection = self._view.get_selection() 130 (model, rows) = selection.get_selected_rows() 131 132 indexes = [self._getIndexForPath(path) for path in rows] 133 indexes.sort() 134 return indexes 135 136 @property 112 137 def hasFlightPairs(self): 113 138 """Determine if the timetable contains any flights.""" … … 125 150 126 151 self._flightPairs = flightPairs 152 153 def getFlightPair(self, index): 154 """Get the flight pair with the given index.""" 155 return self._flightPairs[index] 127 156 128 157 def updateList(self, regularEnabled, vipEnabled, types): … … 140 169 index += 1 141 170 171 def _getIndexForPath(self, path): 172 """Get the index for the given path.""" 173 iter = self._model.get_iter(path) 174 return self._model.get_value(iter, 0) 175 142 176 def _rowActivated(self, flightList, path, column): 143 177 """Called when a row is selected.""" 144 print "_rowActivated"178 self.emit("row-activated", self._getIndexForPath(path)) 145 179 146 180 def _buttonPressEvent(self, widget, event): 147 181 """Called when a mouse button is pressed or released.""" 148 print "_buttonPressEvent", event 182 if event.type!=EVENT_BUTTON_PRESS or event.button!=3 or \ 183 self._popupMenuProducer is None: 184 return 185 186 (path, _, _, _) = self._view.get_path_at_pos(int(event.x), 187 int(event.y)) 188 selection = self._view.get_selection() 189 selection.unselect_all() 190 selection.select_path(path) 191 192 if self._popupMenu is None: 193 self._popupMenu = self._popupMenuProducer() 194 menu = self._popupMenu 195 if pygobject: 196 menu.popup(None, None, None, None, event.button, event.time) 197 else: 198 menu.popup(None, None, None, event.button, event.time) 149 199 150 200 def _selectionChanged(self, selection): 151 201 """Called when the selection has changed.""" 152 print "_selectionChanged" 202 self.emit("selection-changed", self.selectedIndexes) 203 204 def _compareFlights(self, model, iter1, iter2, mainColumn): 205 """Compare the flights at the given iterators according to the given 206 main column.""" 207 index1 = self._model.get_value(iter1, 0) 208 index2 = self._model.get_value(iter2, 0) 209 210 flightPair1 = self._flightPairs[index1] 211 flightPair2 = self._flightPairs[index2] 212 213 result = flightPair1.compareBy(flightPair2, mainColumn) 214 if result==0: 215 for column in Timetable.columnOrdering: 216 if column!=mainColumn: 217 result = flightPair1.compareBy(flightPair2, column) 218 if result!=0: 219 break 220 return result 221 222 def _updateTooltip(self, widget, event): 223 """Update the tooltip for the position of the given event.""" 224 try: 225 (path, col, x, y) = widget.get_path_at_pos( int(event.x), int(event.y)) 226 index = self._getIndexForPath(path) 227 228 flight = self._flightPairs[index].flight0 229 comment = flight.comment 230 date = flight.date 231 232 if comment or date!=const.defaultDate: 233 text = "" 234 if comment: 235 text = comment 236 if date!=const.defaultDate: 237 if text: 238 text += "; " 239 text += date.strftime("%Y-%m-%d") 240 241 self._tooltips.set_tip(widget, text) 242 self._tooltips.enable() 243 else: 244 self._tooltips.set_tip(widget, "") 245 self._tooltips.disable() 246 except Exception, e: 247 print e 248 self._tooltips.set_tip(widget, "") 249 self._tooltips.disable() 153 250 154 251 #----------------------------------------------------------------------------- … … 207 304 #----------------------------------------------------------------------------- 208 305 306 class BookDialog(gtk.Dialog): 307 """The dialog box to select additional data for a booking.""" 308 def __init__(self, timetableWindow, flightPair, planes): 309 """Construct the dialog box.""" 310 super(BookDialog, self).__init__(title = WINDOW_TITLE_BASE + 311 " - " + 312 xstr("timetable_book_title"), 313 parent = timetableWindow) 314 contentArea = self.get_content_area() 315 316 frame = gtk.Frame(xstr("timetable_book_frame_title")) 317 frame.set_size_request(600, -1) 318 319 mainAlignment = gtk.Alignment(xalign = 0.5, yalign = 0.5, 320 xscale = 0.0, yscale = 0.0) 321 mainAlignment.set_padding(padding_top = 16, padding_bottom = 12, 322 padding_left = 8, padding_right = 8) 323 324 table = gtk.Table(6, 2) 325 table.set_row_spacings(8) 326 table.set_col_spacings(16) 327 328 row = 0 329 label = gtk.Label() 330 label.set_markup(xstr("timetable_book_callsign")) 331 label.set_alignment(0.0, 0.5) 332 table.attach(label, 0, 1, row, row + 1) 333 334 text = flightPair.flight0.callsign 335 if flightPair.flight1 is not None: 336 text += " / " + flightPair.flight1.callsign 337 label = gtk.Label(text) 338 label.set_alignment(0.0, 0.5) 339 table.attach(label, 1, 2, row, row + 1) 340 341 row += 1 342 343 label = gtk.Label() 344 label.set_markup(xstr("timetable_book_from_to")) 345 label.set_alignment(0.0, 0.5) 346 table.attach(label, 0, 1, row, row + 1) 347 348 text = flightPair.flight0.departureICAO + " - " + \ 349 flightPair.flight0.arrivalICAO 350 if flightPair.flight1 is not None: 351 text += " - " + flightPair.flight1.arrivalICAO 352 label = gtk.Label(text) 353 label.set_alignment(0.0, 0.5) 354 table.attach(label, 1, 2, row, row + 1) 355 356 row += 1 357 358 if flightPair.flight0.type==ScheduledFlight.TYPE_VIP and \ 359 flightPair.flight0.date!=const.defaultDate: 360 label = gtk.Label() 361 label.set_markup(xstr("timetable_book_flightDate")) 362 label.set_use_underline(True) 363 label.set_alignment(0.0, 0.5) 364 table.attach(label, 0, 1, row, row + 1) 365 366 self._flightDate = gtk.Button() 367 self._flightDate.connect("clicked", self._flightDateClicked) 368 self._flightDate.set_tooltip_text(xstr("timetable_book_flightDate_tooltip")) 369 label.set_mnemonic_widget(self._flightDate) 370 371 table.attach(self._flightDate, 1, 2, row, row + 1) 372 373 self._calendarWindow = calendarWindow = CalendarWindow() 374 calendarWindow.set_transient_for(self) 375 calendarWindow.connect("delete-event", self._calendarWindowDeleted) 376 calendarWindow.connect("date-selected", self._calendarWindowDateSelected) 377 378 self._setDate(flightPair.flight0.date) 379 380 row += 1 381 else: 382 self._flightDate = None 383 self._calendarWindow = None 384 385 label = gtk.Label() 386 label.set_markup(xstr("timetable_book_dep_arr")) 387 label.set_alignment(0.0, 0.5) 388 table.attach(label, 0, 1, row, row + 1) 389 390 text = str(flightPair.flight0.departureTime) + " - " + \ 391 str(flightPair.flight0.arrivalTime) 392 if flightPair.flight1 is not None: 393 text += " / " + str(flightPair.flight1.departureTime) + " - " + \ 394 str(flightPair.flight1.arrivalTime) 395 label = gtk.Label(text) 396 label.set_alignment(0.0, 0.5) 397 table.attach(label, 1, 2, row, row + 1) 398 399 row += 1 400 401 label = gtk.Label() 402 label.set_markup(xstr("timetable_book_duration")) 403 label.set_alignment(0.0, 0.5) 404 table.attach(label, 0, 1, row, row + 1) 405 406 407 duration = flightPair.flight0.duration 408 text = "%02d:%02d" % (duration/3600, (duration%3600)/60) 409 if flightPair.flight1 is not None: 410 duration = flightPair.flight0.duration 411 text += " / %02d:%02d" % (duration/3600, (duration%3600)/60) 412 label = gtk.Label(text) 413 label.set_alignment(0.0, 0.5) 414 table.attach(label, 1, 2, row, row + 1) 415 416 row += 2 417 418 label = gtk.Label() 419 label.set_markup(xstr("timetable_book_tailNumber")) 420 label.set_alignment(0.0, 0.5) 421 table.attach(label, 0, 1, row, row + 1) 422 423 self._planes = planes 424 tailNumbersModel = gtk.ListStore(str) 425 for plane in planes: 426 tailNumbersModel.append((plane.tailNumber,)) 427 428 self._tailNumber = gtk.ComboBox(model = tailNumbersModel) 429 renderer = gtk.CellRendererText() 430 self._tailNumber.pack_start(renderer, True) 431 self._tailNumber.add_attribute(renderer, "text", 0) 432 self._tailNumber.set_tooltip_text(xstr("timetable_book_tailNumber_tooltip")) 433 self._tailNumber.set_active(random.randint(0, len(planes)-1)) 434 435 table.attach(self._tailNumber, 1, 2, row, row + 1) 436 437 mainAlignment.add(table) 438 439 frame.add(mainAlignment) 440 contentArea.pack_start(frame, True, True, 4) 441 442 self.add_button(xstr("button_cancel"), RESPONSETYPE_CANCEL) 443 444 self._okButton = self.add_button(xstr("button_book"), RESPONSETYPE_OK) 445 self._okButton.set_use_underline(True) 446 self._okButton.set_can_default(True) 447 448 @property 449 def plane(self): 450 """Get the currently selected plane.""" 451 return self._planes[self._tailNumber.get_active()] 452 453 @property 454 def date(self): 455 """Get the flight date, if selected.""" 456 return None if self._calendarWindow is None \ 457 else self._calendarWindow.getDate() 458 459 def _setDate(self, date): 460 """Set the date to the given one.""" 461 self._flightDate.set_label(date.strftime("%Y-%m-%d")) 462 self._calendarWindow.setDate(date) 463 464 def _flightDateClicked(self, button): 465 """Called when the flight date button is clicked.""" 466 self._calendarWindow.set_position(gtk.WIN_POS_MOUSE) 467 self.set_focus(self._calendarWindow) 468 self._calendarWindow.show_all() 469 470 def _calendarWindowDeleted(self, window, event): 471 """Called when the flight date window is deleted.""" 472 self._calendarWindow.hide() 473 474 def _calendarWindowDateSelected(self, window): 475 """Called when the flight date window is deleted.""" 476 self._calendarWindow.hide() 477 date = window.getDate() 478 self._flightDate.set_label(date.strftime("%Y-%m-%d")) 479 480 #----------------------------------------------------------------------------- 481 209 482 class TimetableWindow(gtk.Window): 210 483 """The window to display the timetable.""" … … 255 528 256 529 self._flightDate = gtk.Button() 530 self._flightDate.connect("clicked", self._flightDateClicked) 257 531 self._flightDate.connect("clicked", self._flightDateClicked) 258 532 self._flightDate.set_tooltip_text(xstr("timetable_flightdate_tooltip")) … … 317 591 vbox.pack_start(filterAlignment, False, False, 2) 318 592 319 self._timetable = Timetable() 593 self._timetable = Timetable(popupMenuProducer = 594 self._createTimetablePopupMenu) 595 self._timetable.connect("row-activated", self._rowActivated) 596 self._timetable.connect("selection-changed", self._selectionChanged) 320 597 vbox.pack_start(self._timetable, True, True, 2) 321 598 322 alignment = gtk.Alignment(xalign = 0.5, yalign = 0.5,599 alignment = gtk.Alignment(xalign = 1.0, yalign = 0.5, 323 600 xscale = 0.0, yscale = 0.0) 324 self._closeButton = gtk.Button(xstr("button_ok")) 601 buttonBox = gtk.HBox() 602 603 self._bookButton = gtk.Button(xstr("button_book")) 604 self._bookButton.set_use_underline(True) 605 self._bookButton.set_can_default(True) 606 self._bookButton.connect("clicked", self._bookClicked) 607 self._bookButton.set_sensitive(False) 608 buttonBox.pack_start(self._bookButton, False, False, 4); 609 610 self._closeButton = gtk.Button(xstr("button_close")) 611 self._closeButton.set_use_underline(True) 325 612 self._closeButton.connect("clicked", self._closeClicked) 326 alignment.add(self._closeButton) 613 buttonBox.pack_start(self._closeButton, False, False, 4); 614 615 alignment.add(buttonBox) 327 616 vbox.pack_start(alignment, False, False, 2) 328 617 … … 337 626 338 627 self.setDate(datetime.date.today()) 628 629 self._flightPairToBook = None 339 630 340 631 @property … … 423 714 self.isVIPEnabled, 424 715 aircraftTypes) 716 717 def _bookClicked(self, button): 718 """Called when the book button has been clicked.""" 719 self._book(self._timetable.getFlightPair(self._timetable.selectedIndexes[0])) 720 721 def _rowActivated(self, timetable, index): 722 """Called when a row has been activated (e.g. double-clicked) in the 723 timetable.""" 724 self._book(self._timetable.getFlightPair(index)) 725 726 def _selectionChanged(self, timetable, indexes): 727 """Called when the selection has changed. 728 729 It sets the sensitivity of the book button based on whether a row is 730 selected or not.""" 731 self._bookButton.set_sensitive(len(indexes)>0) 732 733 def _book(self, flightPair): 734 """Try to book the given flight pair.""" 735 self._flightPairToBook = flightPair 736 self._gui.getFleet(callback = self._continueBook, 737 busyCallback = self._busyCallback) 738 739 def _busyCallback(self, busy): 740 """Called when the busy state has changed.""" 741 self.set_sensitive(not busy) 742 743 def _continueBook(self, fleet): 744 """Continue booking, once the fleet is available.""" 745 flightPair = self._flightPairToBook 746 aircraftType = flightPair.flight0.aircraftType 747 planes = [plane for plane in fleet 748 if plane.aircraftType == aircraftType] 749 planes.sort(cmp = lambda p1, p2: cmp(p1.tailNumber, p2.tailNumber)) 750 751 dialog = BookDialog(self, flightPair, planes) 752 dialog.show_all() 753 result = dialog.run() 754 dialog.hide() 755 if result==RESPONSETYPE_OK: 756 flightIDs = [flightPair.flight0.id] 757 if flightPair.flight1 is not None: 758 flightIDs.append(flightPair.flight1.id) 759 760 date = dialog.date 761 if date is None: 762 date = self._calendarWindow.getDate() 763 764 self._gui.bookFlights(self._bookFlightsCallback, 765 flightIDs, date, dialog.plane.tailNumber, 766 busyCallback = self._busyCallback) 767 768 def _bookFlightsCallback(self, returned, result): 769 """Called when the booking has finished.""" 770 if returned: 771 dialog = gtk.MessageDialog(parent = self, 772 type = MESSAGETYPE_INFO, 773 message_format = xstr("bookflights_successful")) 774 dialog.format_secondary_markup(xstr("bookflights_successful_secondary")) 775 else: 776 dialog = gtk.MessageDialog(parent = self, 777 type = MESSAGETYPE_ERROR, 778 message_format = xstr("bookflights_failed")) 779 dialog.format_secondary_markup(xstr("bookflights_failed_secondary")) 780 781 dialog.add_button(xstr("button_ok"), RESPONSETYPE_OK) 782 dialog.set_title(WINDOW_TITLE_BASE) 783 784 dialog.run() 785 dialog.hide() 786 787 def _createTimetablePopupMenu(self): 788 """Get the popuop menu for the timetable.""" 789 menu = gtk.Menu() 790 791 menuItem = gtk.MenuItem() 792 menuItem.set_label(xstr("timetable_popup_book")) 793 menuItem.set_use_underline(True) 794 menuItem.connect("activate", self._popupBook) 795 menuItem.show() 796 797 menu.append(menuItem) 798 799 return menu 800 801 def _popupBook(self, menuItem): 802 """Try to book the given flight pair.""" 803 index = self._timetable.selectedIndexes[0] 804 self._book(self._timetable.getFlightPair(index)) -
src/mlx/rpc.py
r858 r859 66 66 "arrivalTime": lambda value: ScheduledFlight._decodeTime(value), 67 67 "duration": lambda value: ScheduledFlight._decodeDuration(value), 68 "type": int, 69 "spec": int 68 "spec": int, 69 "validFrom": lambda value: ScheduledFlight._decodeDate(value), 70 "validTo": lambda value: ScheduledFlight._decodeDate(value), 71 "date": lambda value: ScheduledFlight._decodeDate(value) 70 72 } 71 73 … … 74 76 """Decode the given value as a time value.""" 75 77 return datetime.datetime.strptime(value, "%H:%M:%S").time() 78 79 @staticmethod 80 def _decodeDate(value): 81 """Decode the given value as a date value.""" 82 if not value or value=="0000-00-00": 83 return const.defaultDate 84 else: 85 return datetime.datetime.strptime(value, "%Y-%m-%d").date() 76 86 77 87 @staticmethod … … 90 100 del self.typeCode 91 101 102 self.type = ScheduledFlight.TYPE_VIP if self.spec==1 \ 103 else ScheduledFlight.TYPE_NORMAL 104 del self.spec 105 106 def compareBy(self, other, name): 107 """Compare this flight with the other one according to the given 108 attribute name.""" 109 if name=="callsign": 110 try: 111 cs1 = int(self.callsign[2:]) 112 cs2 = int(other.callsign[2:]) 113 return cmp(cs1, cs2) 114 except: 115 return cmp(self.callsign, other.callsign) 116 else: 117 return cmp(getattr(self, name), getattr(other, name)) 118 92 119 def __repr__(self): 93 120 return "ScheduledFlight<%d, %d, %s, %s (%s) - %s (%s) -> %d, %d>" % \ … … 95 122 self.departureICAO, str(self.departureTime), 96 123 self.arrivalICAO, str(self.arrivalTime), 97 self.duration, self. spec)124 self.duration, self.type) 98 125 99 126 #--------------------------------------------------------------------------------------- … … 104 131 Occasionally, one of the flights may be missing.""" 105 132 @staticmethod 106 def scheduledFlights2Pairs(scheduledFlights ):133 def scheduledFlights2Pairs(scheduledFlights, date): 107 134 """Convert the given list of scheduled flights into a list of flight 108 135 pairs.""" 136 weekday = str(date.weekday()+1) 137 109 138 flights = {} 139 weekdayFlights = {} 110 140 for flight in scheduledFlights: 111 141 flights[flight.id] = flight 142 if (flight.type==ScheduledFlight.TYPE_NORMAL and 143 flight.arrivalICAO!="LHBP" and weekday in flight.days and 144 flight.validFrom<=date and flight.validTo>=date) or \ 145 flight.type==ScheduledFlight.TYPE_VIP: 146 weekdayFlights[flight.id] = flight 112 147 113 148 flightPairs = [] 114 149 115 while flights: 116 (id, flight) = flights.popitem() 117 pairID = flight.pairID 118 if pairID in flights: 119 pairFlight = flights[pairID] 120 if flight.departureICAO=="LHBP" or \ 121 (pairFlight.departureICAO!="LHBP" and id<pairID): 122 flightPairs.append(ScheduledFlightPair(flight, pairFlight)) 123 else: 124 flightPairs.append(ScheduledFlightPair(pairFlight, flight)) 125 del flights[pairID] 126 else: 150 while weekdayFlights: 151 (id, flight) = weekdayFlights.popitem() 152 if flight.type==ScheduledFlight.TYPE_NORMAL: 153 pairID = flight.pairID 154 if pairID in flights: 155 pairFlight = flights[pairID] 156 if flight.departureICAO=="LHBP" or \ 157 (pairFlight.departureICAO!="LHBP" and 158 flight.callsign<pairFlight.callsign): 159 flightPairs.append(ScheduledFlightPair(flight, pairFlight)) 160 else: 161 flightPairs.append(ScheduledFlightPair(pairFlight, flight)) 162 del flights[pairID] 163 if pairID in weekdayFlights: 164 del weekdayFlights[pairID] 165 elif flight.type==ScheduledFlight.TYPE_VIP: 127 166 flightPairs.append(ScheduledFlightPair(flight)) 167 168 flightPairs.sort(cmp = lambda pair1, pair2: 169 cmp(pair1.flight0.date, pair2.flight0.date)) 128 170 129 171 return flightPairs … … 133 175 self.flight0 = flight0 134 176 self.flight1 = flight1 177 178 def compareBy(self, other, name): 179 """Compare this flight pair with the other one according to the given 180 attribute name, considering the first flights.""" 181 return self.flight0.compareBy(other.flight0, name) 182 183 def __repr__(self): 184 return "ScheduledFlightPair<%s, %s, %s>" % \ 185 (self.flight0.callsign, self.flight0.departureICAO, 186 self.flight0.arrivalICAO) 135 187 136 188 #--------------------------------------------------------------------------------------- … … 280 332 _instructions = { 281 333 "status" : lambda value: rpccommon.Plane.str2status(value), 282 "gateNumber" : lambda value: value if value else None 334 "gateNumber" : lambda value: value if value else None, 335 "typeCode": lambda value: BookedFlight._decodeAircraftType(value) 283 336 } 284 337 … … 286 339 """Construct the plane.""" 287 340 RPCObject.__init__(self, value, instructions = Plane._instructions) 341 self.aircraftType = self.typeCode 342 del self.typeCode 288 343 289 344 #--------------------------------------------------------------------------------------- … … 524 579 self._server.getTimetable(sessionID, 525 580 date.strftime("%Y-%m-%d"), 526 date.weekday() +1,581 date.weekday()+1, 527 582 typeCodes)) 528 583 return ScheduledFlightPair.scheduledFlights2Pairs([ScheduledFlight(value) 529 for value in values]) 584 for value in values], 585 date) 586 587 def bookFlights(self, flightIDs, date, tailNumber): 588 """Book the flights with the given IDs on the given date to be flown 589 with the plane of the given tail number.""" 590 values = self._performCall(lambda sessionID: 591 self._server.bookFlights(sessionID, 592 flightIDs, 593 date.strftime("%Y-%m-%d"), 594 tailNumber)) 595 return [BookedFlight(value) for value in values] 530 596 531 597 def _performCall(self, callFn, acceptResults = []): -
src/mlx/web.py
r858 r859 1362 1362 #------------------------------------------------------------------------------ 1363 1363 1364 class BookFlights(RPCRequest): 1365 """Request to book flights.""" 1366 def __init__(self, client, callback, flightIDs, date, tailNumber): 1367 """Construct the request with the given client and callback function.""" 1368 super(BookFlights, self).__init__(client, callback) 1369 self._flightIDs = flightIDs 1370 self._date = date 1371 self._tailNumber = tailNumber 1372 1373 def run(self): 1374 """Perform the login request.""" 1375 result = Result() 1376 1377 result.bookedFlights = self._client.bookFlights(self._flightIDs, 1378 self._date, 1379 self._tailNumber) 1380 1381 return result 1382 1383 #------------------------------------------------------------------------------ 1384 1364 1385 class Handler(threading.Thread): 1365 1386 """The handler for the web services. … … 1463 1484 self._addRequest(GetTimetable(self._rpcClient, callback, date, types)) 1464 1485 1486 def bookFlights(self, callback, flightIDs, date, tailNumber): 1487 """Enqueue a request to book some flights.""" 1488 self._addRequest(BookFlights(self._rpcClient, callback, 1489 flightIDs, date, tailNumber)) 1490 1465 1491 def run(self): 1466 1492 """Process the requests."""
Note:
See TracChangeset
for help on using the changeset viewer.