backend.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. # This file is part of TRS (http://math.kompiler.org)
  2. #
  3. # TRS is free software: you can redistribute it and/or modify it under the
  4. # terms of the GNU Affero General Public License as published by the Free
  5. # Software Foundation, either version 3 of the License, or (at your option) any
  6. # later version.
  7. #
  8. # TRS is distributed in the hope that it will be useful, but WITHOUT ANY
  9. # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  10. # A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  11. # details.
  12. #
  13. # You should have received a copy of the GNU Affero General Public License
  14. # along with TRS. If not, see <http://www.gnu.org/licenses/>.
  15. from tornado.web import RequestHandler, Application
  16. from src.parser import Parser
  17. from tests.parser import ParserWrapper
  18. from src.validation import validate as validate_expression
  19. import sys
  20. import traceback
  21. # Log debug information
  22. from logging import getLogger, DEBUG
  23. getLogger().setLevel(DEBUG)
  24. DEFAULT_PORT = 8888
  25. ROUTER_DEBUG_MODE = True
  26. def get_last_line(handler):
  27. data = handler.get_argument('data')
  28. lines = map(str, data.split('\n'))
  29. # Get the last none empty line.
  30. for i in range(len(lines))[::-1]:
  31. last_line = lines[i].strip()
  32. if last_line:
  33. return last_line
  34. def format_exception(e):
  35. tb = sys.exc_info()[2]
  36. return {'error': str(e), 'traceback': traceback.format_tb(tb)}
  37. class Step(RequestHandler):
  38. def post(self):
  39. try:
  40. last_line = get_last_line(self)
  41. if last_line:
  42. parser = ParserWrapper(Parser)
  43. response = parser.run([last_line])
  44. if response:
  45. response = parser.rewrite(include_step=True,
  46. check_implicit=True)
  47. if response:
  48. hint, step = response
  49. self.write({'step': str(step), 'hint': str(hint)})
  50. return
  51. self.write({'hint': 'No further reduction is possible.'})
  52. except Exception as e:
  53. self.write(format_exception(e))
  54. class Answer(RequestHandler):
  55. def post(self):
  56. try:
  57. last_line = get_last_line(self)
  58. if last_line:
  59. parser = ParserWrapper(Parser)
  60. response = parser.run([last_line])
  61. if response:
  62. steps = parser.rewrite_all(include_steps=True)
  63. if steps:
  64. out = []
  65. for h, s in steps:
  66. out.append(dict(hint=str(h), step=str(s)))
  67. self.write({'steps': out})
  68. return
  69. self.write({'hint': 'No further reduction is possible.'})
  70. except Exception as e:
  71. self.write(format_exception(e))
  72. class Hint(RequestHandler):
  73. def post(self):
  74. try:
  75. last_line = get_last_line(self)
  76. if last_line:
  77. parser = ParserWrapper(Parser)
  78. response = parser.run([last_line])
  79. response = parser.parser.give_hint()
  80. if response:
  81. self.write({'hint': str(response)})
  82. return
  83. self.write({'hint': 'No further reduction is possible.'})
  84. except Exception as e:
  85. self.write(format_exception(e))
  86. class Validate(RequestHandler):
  87. def post(self):
  88. data = self.get_argument('data')
  89. lines = map(str, data.split('\n'))
  90. i = 0
  91. skipped = 0
  92. try:
  93. # Get the first none empty line.
  94. for i in range(0, len(lines)):
  95. last_line = lines[i].strip()
  96. if not last_line: # or last_line in ['?']:
  97. skipped += 1
  98. continue
  99. break
  100. # Validate each none empty line with the following none empty line.
  101. for i in range(i + 1, len(lines)):
  102. line = lines[i].strip()
  103. if not line: # or line in ['?']:
  104. skipped += 1
  105. continue
  106. if not validate_expression(last_line, line):
  107. i -= 1
  108. break
  109. last_line = line
  110. self.write({'validated': i - skipped})
  111. except Exception as e:
  112. i -= 1
  113. self.write(format_exception(e) + {'validated': i - skipped})
  114. urls = [
  115. ('/math\.py/validate', Validate),
  116. ('/math\.py/hint', Hint),
  117. ('/math\.py/step', Step),
  118. ('/math\.py/answer', Answer),
  119. ]
  120. app = Application(urls, debug=ROUTER_DEBUG_MODE)
  121. def start_server(app, port):
  122. from tornado.ioloop import IOLoop
  123. from tornado.options import enable_pretty_logging
  124. enable_pretty_logging()
  125. app.listen(port)
  126. IOLoop.instance().start()
  127. if __name__ == '__main__':
  128. start_server(app, int(sys.argv[1]) if len(sys.argv) > 1 else DEFAULT_PORT)