4 from rospkg
import RosPack
9 from flask
import Flask, render_template, send_from_directory, make_response
10 from waitress.server
import create_server
12 rospy.init_node(
'vizanti_flask_node')
14 param_host = rospy.get_param(
'~host',
'0.0.0.0')
15 param_port = rospy.get_param(
'~port', 5000)
16 param_port_rosbridge = rospy.get_param(
'~port_rosbridge', 5001)
17 param_base_url = rospy.get_param(
'~base_url',
'')
18 param_default_widget_config = rospy.get_param(
'~default_widget_config',
'')
20 public_dir = RosPack().get_path(
'vizanti') +
'/public/'
22 app = Flask(__name__, static_folder=public_dir, template_folder=public_dir)
23 app.debug = rospy.get_param(
'~flask_debug',
True)
25 if param_default_widget_config !=
"":
26 param_default_widget_config = os.path.expanduser(param_default_widget_config)
28 param_default_widget_config = os.path.join(app.static_folder,
"assets/default_layout.json")
31 with open(param_default_widget_config,
'r')
as f:
32 file_content = f.read()
33 js_module = f
"const content = {json.dumps(file_content)};\nexport default content;"
34 response = make_response(js_module)
35 response.headers[
'Content-Type'] =
'application/javascript'
39 templates_dir = os.path.join(app.static_folder, path)
42 for root, dirs, files
in os.walk(templates_dir):
44 if os.path.splitext(file)[1]
in valid_extensions:
45 file_path = os.path.join(root, file)
46 with open(file_path,
'r')
as f:
47 file_content = f.read()
48 file_list.append({
'path': os.path.relpath(file_path, templates_dir),
'content': file_content})
50 js_module = f
"const files = {json.dumps(file_list)};\n\nexport default files;"
53 response = make_response(js_module)
54 response.headers[
'Content-Type'] =
'application/javascript'
58 templates_dir = os.path.join(app.static_folder, path)
61 for root, dirs, files
in os.walk(templates_dir):
63 if os.path.splitext(file)[1]
in valid_extensions:
64 file_list.append(os.path.relpath(os.path.join(root, file), templates_dir))
66 js_module = f
"const paths = {json.dumps(file_list)};\n\nexport default paths;"
68 response = make_response(js_module)
69 response.headers[
'Content-Type'] =
'application/javascript'
72 @app.route(param_base_url +
'/')
74 return render_template(
'index.html', base_url=param_base_url)
76 @app.route(param_base_url +
'/templates/files')
78 return get_files(
"templates", [
'.html',
'.js',
'.css'])
80 @app.route(param_base_url +
'/assets/robot_model/paths')
82 return get_paths(
"assets/robot_model", [
'.png'])
84 @app.route(param_base_url +
'/ros_launch_params')
88 "port_rosbridge": param_port_rosbridge
90 js_module = f
"const params = {json.dumps(params)};\n\nexport default params;"
91 response = make_response(js_module)
92 response.headers[
'Content-Type'] =
'application/javascript'
95 @app.route(param_base_url +
'/default_widget_config')
97 return get_file(param_default_widget_config)
99 @app.route(param_base_url +
'/<path:path>')
101 return send_from_directory(app.static_folder, path)
105 def __init__(self, app, host='0.0.0.0', port=5000):
106 threading.Thread.__init__(self)
109 self.
log = logging.getLogger(
'waitress')
110 self.
log.setLevel(logging.INFO)
111 handler = logging.StreamHandler()
112 handler.setFormatter(logging.Formatter(
113 '[%(levelname)s] [%(asctime)s] [waitress]: %(message)s '
115 self.
log.addHandler(handler)
120 self.
ctx = app.app_context()
130 except KeyboardInterrupt:
137 rospy.loginfo(
"Waitress server shutting down...")
142 rospy.on_shutdown(server.shutdown)