app.py 6.6 KB

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