app.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #!/usr/bin/env python
  2. import json
  3. import os
  4. from flask import Flask, Response, request
  5. from json import JSONEncoder
  6. from aman.AMAN import AMAN
  7. from aman.config.AirportSequencing import AirportSequencing
  8. from aman.config.RunwaySequencing import RunwaySequencing
  9. class InboundEncoder(JSONEncoder):
  10. def default(self, o):
  11. pta = str(o.PlannedArrivalTime)
  12. delimiter = pta.find('.')
  13. if -1 == delimiter:
  14. delimiter = pta.find('+')
  15. return { 'callsign' : o.Callsign, 'fixed' : o.FixedSequence, 'runway' : o.PlannedRunway.Name, 'pta' : pta[0:delimiter] }
  16. class RunwaySequencingEncoder(JSONEncoder):
  17. def default(self, o):
  18. return { 'runway' : o.Runway.Name, 'spacing' : o.Spacing }
  19. if 'AMAN_PATH' not in os.environ:
  20. os.environ['AMAN_PATH'] = 'C:\\Repositories\VATSIM\\AMAN\\aman-sys\\aman'
  21. if 'AMAN_CONFIG_PATH' not in os.environ:
  22. os.environ['AMAN_CONFIG_PATH'] = 'C:\\Repositories\\VATSIM\\AMAN\\config'
  23. aman = AMAN()
  24. app = Flask('AMAN')
  25. version = '0.0.0'
  26. with open(os.environ['AMAN_PATH'] + '\\VERSION') as file:
  27. version = file.readline()
  28. if __name__ == '__main__':
  29. app.run()
  30. @app.route('/aman/airports')
  31. def airports():
  32. # get the current version
  33. print(version)
  34. # get the airports
  35. retval = []
  36. for airport in aman.Workers:
  37. retval.append(airport.Icao)
  38. data = json.dumps({ 'version' : version, 'airports' : retval }, ensure_ascii=True)
  39. return Response(data, status=200, mimetype='application/json')
  40. @app.route('/aman/configuration/<icao>')
  41. def configuration(icao):
  42. airport = aman.findAirport(icao.upper())
  43. if None == airport:
  44. return Response('{}', status=404, mimetype='application/json')
  45. config = airport.SequencingConfiguration
  46. dependencies = []
  47. for dependency in config.RunwayDependencies:
  48. rwy0 = config.runway(dependency[0])
  49. rwy1 = config.runway(dependency[1])
  50. cand1 = [ rwy0.Name, rwy1.Name ]
  51. cand2 = [ rwy1.Name, rwy0.Name ]
  52. found = False
  53. for dep in dependencies:
  54. if cand1 == dep or cand2 == dep:
  55. found = True
  56. break
  57. if False == found:
  58. dependencies.append(cand1)
  59. dictionary = {
  60. 'airport' : airport.Icao,
  61. 'useShallShouldMay' : config.UseShallShouldMay,
  62. 'activeRunways' : config.ActiveArrivalRunways,
  63. 'dependentRunways' : dependencies
  64. }
  65. data = json.dumps(dictionary, ensure_ascii=True, cls=RunwaySequencingEncoder)
  66. return Response(data, status=200, mimetype='application/json')
  67. @app.route('/aman/sequence/<icao>')
  68. def sequence(icao):
  69. airport = aman.findAirport(icao.upper())
  70. if None == airport:
  71. return Response('{}', status=404, mimetype='application/json')
  72. # convert the timestamp
  73. stamp = str(airport.SequencingConfiguration.LastUpdateTimestamp)
  74. delimiter = stamp.find('.')
  75. if -1 == delimiter:
  76. delimiter = stamp.find('+')
  77. dictionary = {
  78. 'airport': airport.Icao,
  79. 'lastConfigurationUpdate': stamp[0:delimiter],
  80. 'sequence': airport.inboundSequence()
  81. }
  82. data = json.dumps(dictionary, ensure_ascii=True, cls=InboundEncoder)
  83. return Response(data, status=200, mimetype='application/json')
  84. @app.route('/aman/configure', methods=['POST'])
  85. def configure():
  86. data = request.get_json()
  87. # validate that the airport exists
  88. if 'airport' not in data:
  89. return Response('{}', status=404, mimetype='application/json')
  90. airport = aman.findAirport(data['airport'].upper())
  91. if None == airport:
  92. return Response('{}', status=404, mimetype='application/json')
  93. # check that all top-level information are available
  94. if 'useShallShouldMay' not in data or 'activeRunways' not in data or 'dependentRunways' not in data:
  95. return Response('{}', status=404, mimetype='application/json')
  96. if False == isinstance(data['useShallShouldMay'], bool) or 0 == len(data['activeRunways']):
  97. return Response('{}', status=404, mimetype='application/json')
  98. # create the toplevel information
  99. config = AirportSequencing(airport.Icao)
  100. config.Airport = data['airport'].upper()
  101. config.UseShallShouldMay = data['useShallShouldMay']
  102. # parse the active runways
  103. for activeRunway in data['activeRunways']:
  104. if 'runway' not in activeRunway or 'spacing' not in activeRunway:
  105. return Response('{}', status=404, mimetype='application/json')
  106. if False == isinstance(activeRunway['runway'], str) or False == isinstance(activeRunway['spacing'], int):
  107. return Response('{}', status=404, mimetype='application/json')
  108. gngRunway = None
  109. for runway in airport.Configuration.GngData.Runways[airport.Icao]:
  110. if runway.Name == activeRunway['runway']:
  111. gngRunway = runway
  112. break
  113. # could not find the runway
  114. if None == gngRunway:
  115. return None
  116. runway = RunwaySequencing(gngRunway)
  117. runway.Spacing = activeRunway['spacing']
  118. config.activateRunway(runway)
  119. # parse the dependent runways
  120. for dependency in data['dependentRunways']:
  121. if 2 != len(dependency) or False == isinstance(dependency[0], str) or False == isinstance(dependency[1], str):
  122. return Response('{}', status=404, mimetype='application/json')
  123. if False == config.addDependency(dependency[0], dependency[1]):
  124. return Response('{}', status=404, mimetype='application/json')
  125. airport.Configuration.assignmentUpdate(config)
  126. airport.configure(config)
  127. return Response('{}', status=200, mimetype='application/json')