Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jihoonl committed Jan 22, 2013
1 parent a34688c commit 51b2025
Show file tree
Hide file tree
Showing 49 changed files with 16,768 additions and 0 deletions.
3 changes: 3 additions & 0 deletions roswww/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/bin
/build
*.pyc
17 changes: 17 additions & 0 deletions roswww/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>roswww</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>
7 changes: 7 additions & 0 deletions roswww/.pydevproject
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?eclipse-pydev version="1.0"?>

<pydev_project>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">Default</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
</pydev_project>
30 changes: 30 additions & 0 deletions roswww/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
cmake_minimum_required(VERSION 2.4.6)
include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)

# Set the build type. Options are:
# Coverage : w/ debug symbols, w/o optimization, w/ code-coverage
# Debug : w/ debug symbols, w/o optimization
# Release : w/o debug symbols, w/ optimization
# RelWithDebInfo : w/ debug symbols, w/ optimization
# MinSizeRel : w/o debug symbols, w/ optimization, stripped binaries
#set(ROS_BUILD_TYPE RelWithDebInfo)

rosbuild_init()

#set the default path for built executables to the "bin" directory
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
#set the default path for built libraries to the "lib" directory
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

#uncomment if you have defined messages
#rosbuild_genmsg()
#uncomment if you have defined services
#rosbuild_gensrv()

#common commands for building c++ executables and libraries
#rosbuild_add_library(${PROJECT_NAME} src/example.cpp)
#target_link_libraries(${PROJECT_NAME} another_library)
#rosbuild_add_boost_directories()
#rosbuild_link_boost(${PROJECT_NAME} thread)
#rosbuild_add_executable(example examples/example.cpp)
#target_link_libraries(example ${PROJECT_NAME})
1 change: 1 addition & 0 deletions roswww/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include $(shell rospack find mk)/cmake.mk
1 change: 1 addition & 0 deletions roswww/ROS_NOBUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
created by rosmake to mark as installed
14 changes: 14 additions & 0 deletions roswww/mainpage.dox
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
\mainpage
\htmlinclude manifest.html

\b roswww

<!--
Provide an overview of your package.
-->

-->


*/
17 changes: 17 additions & 0 deletions roswww/manifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<package>
<description brief="roswww">

roswww

</description>
<author>Jonathan Mace</author>
<license>BSD</license>
<review status="unreviewed" notes=""/>
<url>http://ros.org/wiki/roswww</url>

<depend package="rospy"/>
<depend package="roslib"/>

</package>


120 changes: 120 additions & 0 deletions roswww/nodes/webserver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/usr/bin/env python
import roslib
roslib.load_manifest('roswww')
import rospy

import socket
import subprocess

import tornado.ioloop
import tornado.web

def run(*args):
'''run the provided command and return its stdout'''
args = sum([(arg if type(arg) == list else [arg]) for arg in args], [])
return subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0].strip()

def split_words(text):
'''return a list of lines where each line is a list of words'''
return [line.strip().split() for line in text.split('\n')]

def get_packages():
''' Find the names and locations of all packages '''
lines = split_words(run('rospack', 'list'))
packages = [{ 'name': name, 'path': path } for name, path in lines]
return packages

class MainHandler(tornado.web.RequestHandler):

def initialize(self, packages):
self.packages = packages

def get(self):
self.write("<h1>ROS web server successfully started.</h1><h3>Package List</h3>")
for package in self.packages:
self.write("<div style='font-size: 10px'>"+package['name']+"</div>")

def create_webserver(packages):
handlers = [(r"/", MainHandler, {"packages": packages})]

for package in packages:
handler = ("/"+package['name']+"/(.*)", tornado.web.StaticFileHandler, {"path": package['path']+"/www", "default_filename": "index.html" })
handlers.append(handler)

rospy.loginfo("Webserver initialized for %d packages", len(packages))
application = tornado.web.Application(handlers)

return application

def bind_webserver(application):
""" See if there's a default port, use 80 if not """
default_port, start_port, end_port = get_webserver_params()

""" First, we try the default http port 80 """
bound = bind_to_port(application, default_port)

if not bound:
""" Otherwise bind any available port within the specified range """
bound = bind_in_range(application, start_port, end_port)

return bound

def get_webserver_params():
try:
default_port = rospy.get_param("http/default", 80)
start_port = rospy.get_param("http/range_start", 8000)
end_port = rospy.get_param("http/range_end", 9000)
return (default_port, start_port, end_port)
except socket.error as err:
if err.errno == 111:
# Roscore isn't started or cannot be contacted
rospy.logwarn("Could not contact ROS master. Is a roscore running? Error: %s", err.strerror)
return 80, 8000, 9000
else:
raise

def start_webserver(application):
try:
tornado.ioloop.IOLoop.instance().start()
except KeyboardInterrupt:
rospy.loginfo("Webserver shutting down")

def bind_to_port(application, portno):
rospy.loginfo("Attempting to start webserver on port %d", portno)
try:
application.listen(portno)
rospy.loginfo("Webserver successfully started on port %d", portno)
except socket.error as err:
# Socket exceptions get handled, all other exceptions propagated
if err.errno==13:
rospy.logwarn("Insufficient priveliges to run webserver on port %d. Error: %s", portno, err.strerror)
rospy.loginfo("-- Try re-running as super-user: sudo su; source ~/.bashrc)")
elif err.errno==98:
rospy.logwarn("There is already a webserver running on port %d. Error: %s", portno, err.strerror)
rospy.loginfo("-- Try stopping your web server. For example, to stop apache: sudo /etc/init.d/apache2 stop")
else:
rospy.logerr("An error occurred attempting to listen on port %d: %s", portno, err.strerror)
return False
return True

def bind_in_range(application, start_port, end_port):
if (end_port > start_port):
for i in range(start_port, end_port):
if bind_to_port(application, i):
return True
return False

def run_webserver():
try:
packages = get_packages()
server = create_webserver(packages)
bound = bind_webserver(server)
if (bound):
start_webserver(server)
else:
raise Exception()
except Exception as exc:
rospy.logerr("Unable to bind webserver. Exiting. %s" % exc)

if __name__=='__main__':
run_webserver()
29 changes: 29 additions & 0 deletions roswww/src/tornado/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env python
#
# Copyright 2009 Facebook
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""The Tornado web server and tools."""

from __future__ import absolute_import, division, with_statement

# version is a human-readable version number.

# version_info is a four-tuple for programmatic comparison. The first
# three numbers are the components of the version number. The fourth
# is zero for an official release, positive for a development branch,
# or negative for a release candidate (after the base version number
# has been incremented)
version = "2.3"
version_info = (2, 3, 0, 0)
Loading

0 comments on commit 51b2025

Please sign in to comment.