|
From: <rob...@us...> - 2009-08-19 02:00:43
|
Revision: 22210
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=22210&view=rev
Author: rob_wheeler
Date: 2009-08-19 02:00:32 +0000 (Wed, 19 Aug 2009)
Log Message:
-----------
Bring taskman over from Scott's repository
Added Paths:
-----------
pkg/trunk/sandbox/web/taskman/
pkg/trunk/sandbox/web/taskman/CMakeLists.txt
pkg/trunk/sandbox/web/taskman/Makefile
pkg/trunk/sandbox/web/taskman/manifest.xml
pkg/trunk/sandbox/web/taskman/msg/
pkg/trunk/sandbox/web/taskman/msg/TaskStatus.msg
pkg/trunk/sandbox/web/taskman/src/
pkg/trunk/sandbox/web/taskman/src/taskman.py
pkg/trunk/sandbox/web/taskman/srv/
pkg/trunk/sandbox/web/taskman/srv/StartTask.srv
pkg/trunk/sandbox/web/taskman/srv/StatusUpdate.srv
pkg/trunk/sandbox/web/taskman/srv/StopTask.srv
pkg/trunk/sandbox/web/taskman/test/
pkg/trunk/sandbox/web/taskman/test/joystick.app
pkg/trunk/sandbox/web/taskman/test/pr2_core.app
pkg/trunk/sandbox/web/taskman/test/startTask.py
pkg/trunk/sandbox/web/taskman/test/stopTask.py
pkg/trunk/sandbox/web/taskman/test/talker.app
pkg/trunk/sandbox/web/taskman/test/talker1.app
pkg/trunk/sandbox/web/taskman/test/talker2.app
Added: pkg/trunk/sandbox/web/taskman/CMakeLists.txt
===================================================================
--- pkg/trunk/sandbox/web/taskman/CMakeLists.txt (rev 0)
+++ pkg/trunk/sandbox/web/taskman/CMakeLists.txt 2009-08-19 02:00:32 UTC (rev 22210)
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 2.4.6)
+include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake)
+rospack(taskman)
+genmsg()
+gensrv()
+
Added: pkg/trunk/sandbox/web/taskman/Makefile
===================================================================
--- pkg/trunk/sandbox/web/taskman/Makefile (rev 0)
+++ pkg/trunk/sandbox/web/taskman/Makefile 2009-08-19 02:00:32 UTC (rev 22210)
@@ -0,0 +1 @@
+include $(shell rospack find mk)/cmake.mk
Added: pkg/trunk/sandbox/web/taskman/manifest.xml
===================================================================
--- pkg/trunk/sandbox/web/taskman/manifest.xml (rev 0)
+++ pkg/trunk/sandbox/web/taskman/manifest.xml 2009-08-19 02:00:32 UTC (rev 22210)
@@ -0,0 +1,11 @@
+<package>
+ <description>Task Manager</description>
+ <author>Scott Hassan</author>
+ <license>BSD</license>
+ <review status="na" notes=""/>
+ <url>http://pr.willowgarage.com/wiki/taskman</url>
+
+ <depend package="rospy"/>
+ <depend package="roslaunch"/>
+ <depend package="std_msgs"/>
+</package>
Added: pkg/trunk/sandbox/web/taskman/msg/TaskStatus.msg
===================================================================
--- pkg/trunk/sandbox/web/taskman/msg/TaskStatus.msg (rev 0)
+++ pkg/trunk/sandbox/web/taskman/msg/TaskStatus.msg 2009-08-19 02:00:32 UTC (rev 22210)
@@ -0,0 +1,5 @@
+Header header
+string taskid
+string username
+string status
+time started
Added: pkg/trunk/sandbox/web/taskman/src/taskman.py
===================================================================
--- pkg/trunk/sandbox/web/taskman/src/taskman.py (rev 0)
+++ pkg/trunk/sandbox/web/taskman/src/taskman.py 2009-08-19 02:00:32 UTC (rev 22210)
@@ -0,0 +1,242 @@
+#!/usr/bin/env python
+# Software License Agreement (BSD License)
+#
+# Copyright (c) 2008, Willow Garage, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+# * Neither the name of Willow Garage, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# Revision $Id$
+
+PKG = 'taskman' # this package name
+NAME = 'taskman'
+
+import roslib; roslib.load_manifest(PKG)
+
+from taskman.srv import *
+from taskman.msg import *
+import rospy
+
+import roslib.names
+import roslib.network
+
+from roslaunch.config import ROSLaunchConfig
+from roslaunch.launch import ROSLaunchRunner
+from roslaunch.pmon import pmon_shutdown as _pmon_shutdown
+from roslaunch.xmlloader import *
+
+import subprocess
+
+def getPackagePath(pkg):
+ pkgpath = subprocess.Popen(["rospack", "find", pkg], stdout=subprocess.PIPE).communicate()[0].strip()
+ return pkgpath
+
+class TaskGroup:
+ def __init__(self, manager):
+ self.task = TaskStatus(None, None, None, None, None)
+ self.app = None
+ self.runner = None
+ self.childGroups = []
+ self.manager = manager
+
+ def __del__(self):
+ if self.manager: self.manager = None
+ if self.childGroups: self.childGroups = None
+
+ def launch(self):
+ config = ROSLaunchConfig()
+ loader = XmlLoader()
+ path = getPackagePath(self.app.package)
+ print "pkgpath", path
+ print "launchfile", self.app.launch_file
+ #os.chdir(pkgpath)
+ fn = os.path.join(path, self.app.launch_file)
+ try:
+ loader.load(fn, config)
+ except:
+ self.task.status = "error"
+ self.manager.pub.publish(self.task)
+ return
+
+ self.runner = ROSLaunchRunner(rospy.get_param("/run_id"), config, is_core=False)
+ self.runner.pm.add_process_listener(self)
+ self.runner.launch()
+
+ def stop(self):
+ if not self.runner: return
+ self.runner.stop()
+ self.runner = None
+
+ def process_died(self, process_name, exit_code):
+ #print "process_died", process_name, exit_code
+ #print self.runner.pm.procs
+ if len(self.runner.pm.procs) == 1:
+ self.runner = None
+ #print "ALL DONE!"
+ self.manager._stopTask(self)
+
+
+ def __repr__(self):
+ return "<TaskGroup %s %s %s>" % (self.app.provides, self.app.taskid, len(self.childGroups))
+
+class App:
+ def __init__(self, taskid):
+ # TODO catch file system exception
+ package, app_file = taskid.split('/', 1)
+ path = getPackagePath(package)
+ doc = yaml.load(open(os.path.join(path, app_file)))
+ try:
+ self.taskid = taskid
+ self.app_file = app_file
+ self.name = doc['name']
+ self.package = doc['package']
+ self.provides = doc['provides']
+ self.launch_file = doc['launch_file']
+ self.depends = doc['depends']
+ except KeyError:
+ print "Invalid YAML file"
+
+
+
+class TaskManager:
+ def __init__(self):
+ self.pub = rospy.Publisher("TaskStatus", TaskStatus, self)
+ self._taskGroups = {}
+ self._apps = {}
+
+ def start_task(self, req):
+ app = App(req.taskid)
+ pgroup = None
+ group = self._taskGroups.get(app.provides, None)
+ if group:
+ if group.task.taskid == req.taskid:
+ print "already running"
+ return StartTaskResponse("already running")
+
+ self._stopTask(group)
+
+ if app.depends and app.depends.strip():
+ print "depends", app.depends
+ pgroup = self._taskGroups.get(app.depends, None)
+ if not pgroup:
+ print "no parent task group %s running." % str(app.depends)
+ return StartTaskResponse("no parent task group %s running." % str(app.depends))
+
+ self._apps[req.taskid] = app
+ group = TaskGroup(self)
+ group.app = app
+ if app.provides:
+ self._taskGroups[app.provides] = group
+
+ if pgroup:
+ pgroup.childGroups.append(group)
+
+ print "startTask [%s, %s, %s]" % (req.taskid, app.name, req.username)
+ group.task.taskid = req.taskid
+ group.task.username = req.username
+ group.task.started = rospy.get_rostime()
+ group.task.status = "starting"
+
+ self.pub.publish(group.task)
+
+ group.launch()
+
+ group.task.status = "running"
+ self.pub.publish(group.task)
+
+ return StartTaskResponse("done")
+
+ def showstate(self):
+ print "_" * 40
+ for provides, group in self._taskGroups.items():
+ print provides, group.childGroups
+
+ def _stopTask(self, group):
+ print "_stopTask", group.app.provides
+
+ group.task.status = "stopping"
+ self.pub.publish(group.task)
+
+ print "childGroups", group, group.childGroups
+ for cgroup in group.childGroups[:]:
+ self._stopTask(cgroup)
+
+ group.stop()
+
+ group.task.status = "stopped"
+ self.pub.publish(group.task)
+
+ if group.app.depends:
+ pgroup = self._taskGroups.get(group.app.depends.strip(), None)
+ if pgroup:
+ pgroup.childGroups.remove(group)
+
+ if group.app.provides:
+ print "removing", group.app.provides
+ del self._taskGroups[group.app.provides]
+
+ def stop_task(self, req):
+ app = self._apps[req.taskid]
+
+ group = self._taskGroups.get(app.provides, None)
+ if not group:
+ msg = "no such group: " + str(app.provides)
+ return StopTaskResponse(msg)
+
+ self._stopTask(group)
+
+ del self._apps[req.taskid]
+
+ return StopTaskResponse("done")
+
+ def status_update(self, req):
+ for provides, group in self._taskGroups.items():
+ self.pub.publish(group.task)
+ return StatusUpdateResponse("done")
+
+
+ def peer_subscribe(self, topic_name, topic_publish, peer_publish):
+ pass
+
+ def peer_unsubscribe(self, topic_name, numPeers):
+ pass
+
+
+def server():
+ rospy.init_node(NAME)
+
+ tm = TaskManager()
+ s1 = rospy.Service('start_task', StartTask, tm.start_task)
+ s2 = rospy.Service('stop_task', StopTask, tm.stop_task)
+ s3 = rospy.Service('status_update', StatusUpdate, tm.status_update)
+
+ # spin() keeps Python from exiting until node is shutdown
+ rospy.spin()
+
+if __name__ == "__main__":
+ server()
Property changes on: pkg/trunk/sandbox/web/taskman/src/taskman.py
___________________________________________________________________
Added: svn:executable
+ *
Added: pkg/trunk/sandbox/web/taskman/srv/StartTask.srv
===================================================================
--- pkg/trunk/sandbox/web/taskman/srv/StartTask.srv (rev 0)
+++ pkg/trunk/sandbox/web/taskman/srv/StartTask.srv 2009-08-19 02:00:32 UTC (rev 22210)
@@ -0,0 +1,4 @@
+string taskid
+string username
+---
+string status
Added: pkg/trunk/sandbox/web/taskman/srv/StatusUpdate.srv
===================================================================
--- pkg/trunk/sandbox/web/taskman/srv/StatusUpdate.srv (rev 0)
+++ pkg/trunk/sandbox/web/taskman/srv/StatusUpdate.srv 2009-08-19 02:00:32 UTC (rev 22210)
@@ -0,0 +1,2 @@
+---
+string status
\ No newline at end of file
Added: pkg/trunk/sandbox/web/taskman/srv/StopTask.srv
===================================================================
--- pkg/trunk/sandbox/web/taskman/srv/StopTask.srv (rev 0)
+++ pkg/trunk/sandbox/web/taskman/srv/StopTask.srv 2009-08-19 02:00:32 UTC (rev 22210)
@@ -0,0 +1,4 @@
+string taskid
+string username
+---
+string status
\ No newline at end of file
Added: pkg/trunk/sandbox/web/taskman/test/joystick.app
===================================================================
--- pkg/trunk/sandbox/web/taskman/test/joystick.app (rev 0)
+++ pkg/trunk/sandbox/web/taskman/test/joystick.app 2009-08-19 02:00:32 UTC (rev 22210)
@@ -0,0 +1,7 @@
+name: Joystick
+package: pr2_core
+launch_file: teleop_joystick_tuck.launch
+description: Move the base with the joystick
+icon:
+provides:
+depends: pr2_core
Added: pkg/trunk/sandbox/web/taskman/test/pr2_core.app
===================================================================
--- pkg/trunk/sandbox/web/taskman/test/pr2_core.app (rev 0)
+++ pkg/trunk/sandbox/web/taskman/test/pr2_core.app 2009-08-19 02:00:32 UTC (rev 22210)
@@ -0,0 +1,7 @@
+name: PR2 Core
+package: pr2_core
+launch_file: pr2_core.launch
+description: Bring up most of the PR2
+icon:
+provides: pr2_core
+depends: pr2_core
Added: pkg/trunk/sandbox/web/taskman/test/startTask.py
===================================================================
--- pkg/trunk/sandbox/web/taskman/test/startTask.py (rev 0)
+++ pkg/trunk/sandbox/web/taskman/test/startTask.py 2009-08-19 02:00:32 UTC (rev 22210)
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+# Software License Agreement (BSD License)
+#
+# Copyright (c) 2008, Willow Garage, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+# * Neither the name of Willow Garage, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# Revision $Id$
+
+## Simple demo of a rospy service client that calls a service to add
+## two integers.
+
+PKG = 'taskman' # this package name
+
+import roslib; roslib.load_manifest(PKG)
+
+import sys
+import os
+import string
+
+import rospy
+
+# imports the AddTwoInts service
+from taskman.srv import *
+
+def startTask(task):
+ rospy.wait_for_service('start_task')
+
+ try:
+ # create a handle to the add_two_ints service
+ start_task = rospy.ServiceProxy('start_task', StartTask)
+ resp1 = start_task(task, "hassan")
+
+ return resp1.status
+ except rospy.ServiceException, e:
+ print "Service call failed: %s"%e
+
+if __name__ == "__main__":
+ startTask(sys.argv[1])
Property changes on: pkg/trunk/sandbox/web/taskman/test/startTask.py
___________________________________________________________________
Added: svn:executable
+ *
Added: pkg/trunk/sandbox/web/taskman/test/stopTask.py
===================================================================
--- pkg/trunk/sandbox/web/taskman/test/stopTask.py (rev 0)
+++ pkg/trunk/sandbox/web/taskman/test/stopTask.py 2009-08-19 02:00:32 UTC (rev 22210)
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+# Software License Agreement (BSD License)
+#
+# Copyright (c) 2008, Willow Garage, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+# * Neither the name of Willow Garage, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# Revision $Id$
+
+## Simple demo of a rospy service client that calls a service to add
+## two integers.
+
+PKG = 'taskman' # this package name
+
+import roslib; roslib.load_manifest(PKG)
+
+import sys
+import os
+import string
+
+import rospy
+
+from taskman.srv import *
+
+def stopTask(task):
+ rospy.wait_for_service('stop_task')
+
+ try:
+ stop_task = rospy.ServiceProxy('stop_task', StopTask)
+ resp1 = stop_task(task, "hassan")
+
+ return resp1.status
+ except rospy.ServiceException, e:
+ print "Service call failed: %s"%e
+
+if __name__ == "__main__":
+ stopTask(sys.argv[1])
Property changes on: pkg/trunk/sandbox/web/taskman/test/stopTask.py
___________________________________________________________________
Added: svn:executable
+ *
Added: pkg/trunk/sandbox/web/taskman/test/talker.app
===================================================================
--- pkg/trunk/sandbox/web/taskman/test/talker.app (rev 0)
+++ pkg/trunk/sandbox/web/taskman/test/talker.app 2009-08-19 02:00:32 UTC (rev 22210)
@@ -0,0 +1,7 @@
+name: Talker/Listener
+package: rospy_tutorials
+launch_file: 001_talker_listener/talker_listener.launch
+description: ROS's hello world equivilant
+icon:
+provides: talkers
+depends:
Added: pkg/trunk/sandbox/web/taskman/test/talker1.app
===================================================================
--- pkg/trunk/sandbox/web/taskman/test/talker1.app (rev 0)
+++ pkg/trunk/sandbox/web/taskman/test/talker1.app 2009-08-19 02:00:32 UTC (rev 22210)
@@ -0,0 +1,7 @@
+name: Talker/Listener
+package: rospy_tutorials
+launch_file: 001_talker_listener/talker_listener.launch
+description: ROS's hello world equivilant
+icon:
+provides: talk
+depends: talkers
Added: pkg/trunk/sandbox/web/taskman/test/talker2.app
===================================================================
--- pkg/trunk/sandbox/web/taskman/test/talker2.app (rev 0)
+++ pkg/trunk/sandbox/web/taskman/test/talker2.app 2009-08-19 02:00:32 UTC (rev 22210)
@@ -0,0 +1,7 @@
+name: Talker/Listener
+package: rospy_tutorials
+launch_file: 001_talker_listener/talker_listener.launch
+description: ROS's hello world equivilant
+icon:
+provides: talk
+depends: talkers
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rob...@us...> - 2009-08-19 22:44:55
|
Revision: 22345
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=22345&view=rev
Author: rob_wheeler
Date: 2009-08-19 22:44:45 +0000 (Wed, 19 Aug 2009)
Log Message:
-----------
Move taskman to launchman
Added Paths:
-----------
pkg/trunk/sandbox/web/launchman/
Removed Paths:
-------------
pkg/trunk/sandbox/web/taskman/
Property changes on: pkg/trunk/sandbox/web/launchman
___________________________________________________________________
Added: svn:mergeinfo
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wgh...@us...> - 2009-08-20 21:41:28
|
Revision: 22475
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=22475&view=rev
Author: wghassan
Date: 2009-08-20 21:41:17 +0000 (Thu, 20 Aug 2009)
Log Message:
-----------
pyclearsilver initial checkin. used by webui
Added Paths:
-----------
pkg/trunk/sandbox/web/pyclearsilver/
pkg/trunk/sandbox/web/pyclearsilver/manifest.xml
pkg/trunk/sandbox/web/pyclearsilver/src/
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/CSPage.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/__init__.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/autoreloader.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/cgistarter.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/fixedpoint.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/guid.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/handle_error.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/hdfhelp.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/httpResponses.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/log.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/odb.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/odb_mysql.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/odb_postgres.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/odb_sqlite.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/odb_sqlite3.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/profiler.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/rebuild_sqlitedb.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/scaffold.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/templates/
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/templates/edit.cs
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/templates/list.cs
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/templates/show.cs
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/templates/sorttable.js
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/templates/style.css
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/templates/tables.cs
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/test.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/test_odb.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/trans/
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/trans/__init__.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/trans/db_trans.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/trans/trans.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/trans/tstart.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/who_calls.py
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/wordwrap.py
Added: pkg/trunk/sandbox/web/pyclearsilver/manifest.xml
===================================================================
--- pkg/trunk/sandbox/web/pyclearsilver/manifest.xml (rev 0)
+++ pkg/trunk/sandbox/web/pyclearsilver/manifest.xml 2009-08-20 21:41:17 UTC (rev 22475)
@@ -0,0 +1,11 @@
+<package>
+<description brief="Python Clearsilver">
+Converts ROS topics to JSON for Web requests.
+</description>
+<author>Scott Hassan/ha...@wi...</author>
+<license>BSD</license>
+<review status="experimental" notes=""/>
+<url>http://pr.willowgarage.com/wiki/iros</url>
+<sysdepend os="ubuntu" package="python-clearsilver"/>
+</package>
+
Property changes on: pkg/trunk/sandbox/web/pyclearsilver/manifest.xml
___________________________________________________________________
Added: svn:executable
+ *
Added: pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/CSPage.py
===================================================================
--- pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/CSPage.py (rev 0)
+++ pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/CSPage.py 2009-08-20 21:41:17 UTC (rev 22475)
@@ -0,0 +1,423 @@
+#!/usr/bin/env python
+
+import neo_cgi, neo_cs
+import sys, os, string
+import time
+from log import *
+
+# errors thrown...
+NoPageName = "NoPageName"
+NoDisplayMethod = "NoDisplayMethod"
+
+# errors signaled back to here
+Redirected = "Redirected"
+DisplayDone = "DisplayDone"
+DisplayError = "DisplayError"
+
+class Context:
+ def __init__ (self):
+ self.argv = sys.argv
+ self.stdin = sys.stdin
+ self.stdout = sys.stdout
+ self.stderr = sys.stderr
+ self.environ = os.environ
+
+ def setStatus(self, request, status):
+ if request:
+ request['status'] = str(status)
+
+
+class CSPage:
+ _pagename = None
+
+ def __init__(self, context, pagename=None,readDefaultHDF=1,israwpage=0,
+ parseCGI=1, makePUT=0, **parms):
+ if pagename is None: pagename = self._pagename
+ if not pagename: raise NoPageName, "missing pagename"
+ self.pagename = pagename
+ self.readDefaultHDF = readDefaultHDF
+ self._israwpage = israwpage
+ self.context = context
+ self._pageparms = parms
+
+ self._error_template = None
+
+ self.page_start_time = time.time()
+
+ if makePUT:
+ context.environ['REQUEST_METHOD'] = 'PUT'
+
+ neo_cgi.cgiWrap(context.stdin, context.stdout, context.environ)
+ neo_cgi.IgnoreEmptyFormVars(1)
+ self.ncgi = neo_cgi.CGI()
+
+ if parseCGI:
+ self.ncgi.parse()
+
+ self._path_num = 0
+ domain = self.ncgi.hdf.getValue("CGI.ServerName","")
+ domain = self.ncgi.hdf.getValue("HTTP.Host", domain)
+ self.domain = domain
+ self.subclassinit()
+ self.setPaths([self.ncgi.hdf.getValue("CGI.DocumentRoot","")])
+
+ self._sent_headers = 0
+ self._reply_headers = {}
+ self._reply_code = 200
+
+ if self.ncgi.hdf.getValue("CGI.HTTPS", ""):
+ self.http = "https://"
+ else:
+ self.http = "http://"
+
+ def __setitem__(self, key, value):
+ self._reply_headers[string.lower(key)] = value
+ self.ncgi.hdf.setValue("cgiout.other.%s" % key, "%s: %s" % (key, value))
+
+ def __getitem__(self, key):
+ return self._reply_headers[string.lower(key)]
+
+ def has_key(self, key):
+ return self._reply_headers.has_key(string.lower(key))
+
+ def subclassinit(self):
+ pass
+
+ def clearPaths(self):
+ self.ncgi.hdf.removeTree("hdf.loadpaths")
+
+ def setPaths(self, paths):
+ for path in paths:
+ self.ncgi.hdf.setValue("hdf.loadpaths.%d" % self._path_num, path)
+ self._path_num = self._path_num + 1
+
+ def redirectUri(self,redirectTo):
+ ncgi = self.ncgi
+ if ncgi.hdf.getIntValue("Cookie.debug",0) == 1:
+ ncgi.hdf.setValue("CGI.REDIRECT_TO",redirectTo)
+# ncgi.display("dbg/redirect.cs")
+
+ cs = neo_cs.CS(ncgi.hdf)
+ self['Content-Type'] = "text/html"
+ template = """
+Redirect
+<br><br>
+<a href="<?cs var:CGI.REDIRECT_TO ?>"><?cs var:CGI.REDIRECT_TO ?></a>
+"""
+ cs.parseStr(template)
+ page = cs.render()
+
+ self.push(page)
+
+ self.push("<PRE>\n")
+ self.push(neo_cgi.htmlEscape(ncgi.hdf.dump()) + "\n")
+ self.push("</PRE>\n")
+ raise DisplayDone
+
+ self.context.setStatus(self, 302)
+ self.ncgi.redirectUri(redirectTo)
+ raise Redirected, "redirected To: %s" % redirectTo
+
+ ## ----------------------------------
+ ## methods to be overridden in subclass when necessary:
+
+ def setup(self):
+ pass
+
+ def display(self):
+ raise NoDisplayMethod, "no display method present in %s" % repr(self)
+
+ def main(self):
+ hdf = self.ncgi.hdf
+
+ def __call(method):
+ if method.im_func.func_code.co_argcount == 2:
+ method(hdf)
+ else:
+ method()
+
+ __call(self.setup)
+
+ self.handle_actions()
+
+ __call(self.display)
+
+ ## ----------------------------------
+
+ def handle_actions(self):
+ hdf = self.ncgi.hdf
+ #warn(hdf.writeString())
+ hdfobj = hdf.getObj("Query.Action")
+ if hdfobj:
+ firstchild = hdfobj.child()
+ if firstchild:
+ action = firstchild.name()
+ if firstchild.next():
+ raise "multiple actions present!!!"
+
+ method_name = "Action_%s" % action
+ method = getattr(self,method_name)
+ if method.im_func.func_code.co_argcount == 2:
+ apply(method,[hdf])
+ else:
+ apply(method,[])
+
+ def start(self):
+ SHOULD_DISPLAY = 1
+ if self._israwpage:
+ SHOULD_DISPLAY = 0
+
+ ncgi = self.ncgi
+
+ if self.readDefaultHDF:
+ try:
+ if not self.pagename is None:
+ ncgi.hdf.readFile("%s.hdf" % self.pagename)
+ except:
+ debug("Error reading HDF file: %s.hdf" % (self.pagename))
+
+ DISPLAY_ERROR = 0
+ ERROR_MESSAGE = ""
+ # call page main function!
+ try:
+ self.main()
+ except DisplayDone:
+ SHOULD_DISPLAY = 0
+ except Redirected:
+ # catch redirect exceptions
+ SHOULD_DISPLAY = 0
+ except DisplayError, num:
+ ncgi.hdf.setValue("Query.error", str(num))
+ if self._error_template:
+ ncgi.hdf.setValue("Content", self._error_template)
+ else:
+ DISPLAY_ERROR = 1
+ except:
+ SHOULD_DISPLAY = 0
+ DISPLAY_ERROR = 1
+
+ import handle_error
+ handle_error.handleException("Display Failed!")
+ ERROR_MESSAGE = handle_error.exceptionString()
+
+ if DISPLAY_ERROR:
+ #print "Content-Type: text/html\n\n"
+
+ # print the page
+
+ self['Content-Type'] = "text/html"
+
+ # print the page
+
+ self.push("<H1> Error in Page </H1>\n")
+ self.push("A copy of this error report has been submitted to the developers. ")
+ self.push("The details of the error report are below.")
+
+ self.push("<PRE>")
+ self.push(handle_error.exceptionString())
+ self.push("</PRE>\n")
+
+ # print debug info always on page error...
+ self.push("<HR>\n")
+ self.push("<PRE>")
+ self.push(neo_cgi.htmlEscape(ncgi.hdf.dump()))
+ self.push("</PRE>")
+
+
+ etime = time.time() - self.page_start_time
+ ncgi.hdf.setValue("CGI.debug.execute_time","%f" % (etime))
+ #warn("excute_time", etime)
+
+ if SHOULD_DISPLAY and self.pagename:
+ debug_output = ncgi.hdf.getIntValue("page.debug",ncgi.hdf.getIntValue("Cookie.debug",0))
+
+ # hijack the built-in debug output method...
+ if ncgi.hdf.getValue("Query.debug","") == ncgi.hdf.getValue("Config.DebugPassword","1"):
+ ncgi.hdf.setValue("Config.DebugPassword","CSPage.py DEBUG hijack (%s)" %
+ ncgi.hdf.getValue("Config.DebugPassword",""))
+ debug_output = 1
+
+ if not debug_output:
+ ncgi.hdf.setValue("Config.CompressionEnabled","1")
+ else:
+ ncgi.hdf.setValue("Config.CompressionEnabled","0")
+
+ # default display
+ template_name = ncgi.hdf.getValue("Content","%s.cs" % self.pagename)
+ # ncgi.hdf.setValue ("cgiout.charset", "utf-8");
+
+ try:
+ self.context.setStatus(self, 200)
+ ncgi.display(template_name)
+ self._sent_headers = 1
+ except:
+ self['Content-Type'] = 'text/html'
+ self.push("CSPage: Error occured\n")
+ import handle_error
+ self.push("<pre>" + handle_error.exceptionString() + "</pre>")
+ debug_output = 1
+
+
+ # debug output
+ if debug_output:
+ self.push("<HR>\n")
+ self.push("Execution Time: %5.3f<BR><HR>" % (etime))
+ self.push("<PRE>")
+ self.push(neo_cgi.htmlEscape(ncgi.hdf.dump()))
+ self.push("</PRE>")
+ # ncgi.hdf.setValue("hdf.DEBUG",ncgi.hdf.dump())
+ # ncgi.display("debug.cs")
+
+ script_name = ncgi.hdf.getValue("CGI.ScriptName","")
+ if script_name:
+ script_name = string.split(script_name,"/")[-1]
+
+ log ("[%s] etime/dtime: %5.3f/%5.3f %s (%s)" % (self.domain, etime, time.time() - etime - self.page_start_time, script_name, self.pagename))
+ return self._reply_code
+
+ # a protected output function to catch the output errors that occur when
+ # the server is either restarted or the user pushes the stop button on the
+ # browser
+ def output(self, str):
+ try:
+ if len(str) > 8196:
+ import cStringIO
+ fp = cStringIO.StringIO(str)
+ while 1:
+ data = fp.read(8196*8)
+ if not data: break
+ self.context.stdout.write(data)
+ else:
+ self.context.stdout.write(str)
+ except IOError, reason:
+ log("IOError: %s" % (repr(reason)))
+ raise DisplayDone
+
+ def done(self):
+ if not self._sent_headers: self.error(500)
+ self._sent_headers = 0
+
+ raise DisplayDone
+
+ def push(self, data):
+ if not self._sent_headers:
+ headerdata = self.send_headers(dont_send=1)
+ self.output(headerdata + data)
+ else:
+ self.output(data)
+
+
+ def send_headers(self, dont_send=0):
+ self._sent_headers = 1
+
+ message = gHTTPResponses[self._reply_code]
+
+ if self._reply_code != 200:
+ #self['status'] = "%s %s" % (self._reply_code, message)
+ #self.context.setStatus(self, self._reply_code)
+ pass
+ self.context.setStatus(self, self._reply_code)
+ self['connection'] = 'close'
+
+ headers = []
+ #headers.append(self.response(self._reply_code))
+ for (key, value) in self._reply_headers.items():
+ headers.append('%s: %s' % (key, value))
+ headers.append('\r\n')
+
+ if dont_send == 0:
+ self.push(string.join(headers, '\r\n'))
+ else:
+ return string.join(headers, '\r\n')
+
+
+ def allQuery (self, s):
+ l = []
+ if self.ncgi.hdf.getValue ("Query.%s.0" % s, ""):
+ obj = self.ncgi.hdf.getChild ("Query.%s" % s)
+ while obj:
+ l.append(obj.value())
+ obj = obj.next()
+ else:
+ t = self.ncgi.hdf.getValue ("Query.%s" % s, "")
+ if t: l.append(t)
+ return l
+
+
+ def error(self, code, reason=None):
+ self._reply_code = code
+ message = gHTTPResponses[code]
+ s = DEFAULT_ERROR_MESSAGE % {
+ 'code': code, 'message': message, 'reason': reason
+ }
+
+# self['Content-Length'] = len(s)
+# self['Content-Type'] = 'text/html'
+
+# self.push(s)
+ self.context.stdout.write("Content-Type: text/html\n")
+ self.context.setStatus(self, code)
+ self.context.stdout.write("Status: %s\n" % code)
+ self.context.stdout.write(s)
+# self.done()
+
+ raise DisplayDone
+
+
+
+gHTTPResponses = {
+ 100: "Continue",
+ 101: "Switching Protocols",
+ 200: "OK",
+ 201: "Created",
+ 202: "Accepted",
+ 203: "Non-Authoritative Information",
+ 204: "No Content",
+ 205: "Reset Content",
+ 206: "Partial Content",
+ 300: "Multiple Choices",
+ 301: "Moved Permanently",
+ 302: "Moved Temporarily",
+ 303: "See Other",
+ 304: "Not Modified",
+ 305: "Use Proxy",
+ 400: "Bad Request",
+ 401: "Unauthorized",
+ 402: "Payment Required",
+ 403: "Forbidden",
+ 404: "Not Found",
+ 405: "Method Not Allowed",
+ 406: "Not Acceptable",
+ 407: "Proxy Authentication Required",
+ 408: "Request Time-out",
+ 409: "Conflict",
+ 410: "Gone",
+ 411: "Length Required",
+ 412: "Precondition Failed",
+ 413: "Request Entity Too Large",
+ 414: "Request-URI Too Large",
+ 415: "Unsupported Media Type",
+ 500: "Internal Server Error",
+ 501: "Not Implemented",
+ 502: "Bad Gateway",
+ 503: "Service Unavailable",
+ 504: "Gateway Time-out",
+ 505: "HTTP Version not supported"
+ }
+
+# Default error message
+DEFAULT_ERROR_MESSAGE = string.join(
+ ['',
+ '<head>',
+ '<title>%(code)d %(message)s</title>',
+ '</head>',
+ '<body>',
+ '<h1>%(message)s</h1>',
+ '<p>Error code %(code)d.',
+ '<p>Message: %(message)s.',
+ '<p>Reason:\n <pre>%(reason)s</pre>',
+ '</body>',
+ ''
+ ],
+ '\r\n'
+ )
Added: pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/__init__.py
===================================================================
--- pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/__init__.py (rev 0)
+++ pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/__init__.py 2009-08-20 21:41:17 UTC (rev 22475)
@@ -0,0 +1,9 @@
+versionMajor = 2
+versionMinor = 0
+
+version = (versionMajor, versionMinor)
+
+import odb
+import hdfhelp
+
+
Added: pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/autoreloader.py
===================================================================
--- pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/autoreloader.py (rev 0)
+++ pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/autoreloader.py 2009-08-20 21:41:17 UTC (rev 22475)
@@ -0,0 +1,61 @@
+#!/neo/opt/bin/python
+
+
+import ihooks, os, sys
+from pyclearsilver.log import *
+
+#ihooks.install(AutoReload())
+
+class AutoReload(ihooks.ModuleImporter):
+ def __init__(self):
+ ihooks.ModuleImporter.__init__(self)
+ self.datestamps = {}
+
+ def import_module(self,name,globals={},locals={},fromlist={}):
+# warn("import_module", name)
+ testpath = name + ".py"
+
+ # stat the file if we have it
+ if os.path.isfile(testpath):
+ stinfo = os.stat(testpath)
+ else:
+ stinfo = None
+
+ if sys.modules.has_key(name):
+# warn("reimporting", testpath)
+ # already imported
+ m = ihooks.ModuleImporter.import_module(self,name,globals,locals,fromlist)
+ try:
+ testpath = m.__file__
+ if os.path.isfile(testpath):
+ stinfo = os.stat(testpath)
+ except AttributeError: pass
+
+ if stinfo:
+
+ stored_time = self.datestamps.get(testpath,0)
+ if stored_time < stinfo.st_mtime:
+
+ self.datestamps[testpath] = stinfo.st_mtime
+ if stored_time:
+ warn("---------------------", name, "changed reloading", stored_time, stinfo.st_mtime, os.getcwd())
+
+ reload(sys.modules[name])
+ else :
+# warn("loading for the first time", testpath)
+ if stinfo:
+ self.datestamps[testpath] = stinfo.st_mtime
+ m = ihooks.ModuleImporter.import_module(self,name,globals,locals,fromlist)
+ try:
+ testpath = m.__file__
+ stinfo = os.stat(testpath)
+ if os.path.isfile(testpath):
+ self.datestamps[testpath] = stinfo.st_mtime
+ except AttributeError:
+ pass
+
+ return m
+
+
+warn("**********************8 installing autoreload")
+ihooks.install(AutoReload())
Property changes on: pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/autoreloader.py
___________________________________________________________________
Added: svn:executable
+ *
Added: pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/cgistarter.py
===================================================================
--- pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/cgistarter.py (rev 0)
+++ pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/cgistarter.py 2009-08-20 21:41:17 UTC (rev 22475)
@@ -0,0 +1,316 @@
+#! /usr/bin/env python
+
+import os, sys, string, time, string
+from pyclearsilver.log import *
+
+#debugfull()
+debugoff()
+
+import gc
+
+try:
+ import warnings
+ warnings.resetwarnings()
+ warnings.filterwarnings("ignore")
+except ImportError:
+ pass
+
+import neo_cgi, neo_cs, neo_util
+
+from pyclearsilver import CSPage
+
+import mimetypes
+mimetypes.init(["/etc/mime.types"])
+
+
+gConfig = None
+def setConfig(config):
+ global gConfig
+ gConfig = config
+
+ if not hasattr(gConfig, "gRequireUsername"): gConfig.gRequireUsername = 0
+ if not hasattr(gConfig, "gDataFilePaths"): gConfig.gDataFilePaths = []
+
+
+def split_path(path):
+ # strip off leading slash, it's no fun!
+ return string.split(path, '/')[1:]
+
+
+class Page:
+ def __init__(self, context):
+ self.context = context
+
+ def setupvars(self):
+
+ self.path = self.context.environ.get("PATH_INFO", '')
+
+ script_name = self.context.environ.get("SCRIPT_NAME",'')
+
+ ## handle the case where the site is located at '/'
+ if not self.path:
+ self.path = script_name
+ script_name = '/'
+
+
+ def start(self):
+ self.setupvars()
+
+ self._path = self.path
+
+ rpath = self._path
+ if not rpath: rpath = '/'
+
+ if rpath == "/": rpath = gConfig.gDefaultPage
+
+ self.path = split_path(rpath)
+
+ username = None
+
+ if len(self.path) == 0:
+ warn("no such path", self.path)
+ self.error(404)
+ return 404
+
+ ## the url form should be:
+ ## /baseuri/username/module/script.py
+
+ cwd = os.getcwd()
+ debug("CWD", cwd)
+
+ module = gConfig.gDefaultModule
+
+ if hasattr(gConfig, "gDataFilePaths"):
+ if self.path[0] in gConfig.gDataFilePaths:
+ fn = apply(os.path.join, [cwd,] + self.path)
+ return outputFile(self.context, fn)
+
+ if gConfig.gRequireUsername:
+ username = self.path[0]
+ n = 1
+ else:
+ n = 0
+
+ debug("self.path", self.path)
+
+ if len(self.path) > 1:
+ module = self.path[n]
+ n = n + 1
+
+ moduleRootPath = apply(os.path.join, ["mod", module])
+ handlerRoot = apply(os.path.join, ["mod", module, "cgibin"])
+ moduleTemplatePath = apply(os.path.join, [cwd, "mod", module, "templates"])
+ systemTemplatePath = apply(os.path.join, [cwd, "templates"])
+ systemJLIBPath = apply(os.path.join, [cwd, "jslib"])
+
+ fn = apply(os.path.join, [cwd, moduleRootPath,] + self.path[n:])
+ debug("fn", fn)
+
+ ## if requesting a file, then just output it to the browser.
+ if os.path.isfile(fn):
+ return outputFile(self.context, fn)
+
+ ## manage the Python module Path
+# sys.path.insert(0, os.path.join(cwd, "pysrc"))
+# sys.path.insert(0, os.path.join(cwd, "pysrc", "base"))
+
+ sys.path.insert(0, os.path.abspath(moduleRootPath))
+ #sys.path.insert(0, os.path.abspath(handlerRoot))
+
+ debug("sys.path", sys.path)
+
+ handlerPath = ''
+
+ ## find the first *real* file in the path
+ ## the rest of the path becomes the pathinfo.
+ m = n
+ for m in range(len(self.path)-1, n-2, -1):
+ handlerPath = apply(os.path.join, [handlerRoot, ] + self.path[n:m+1])
+# warn(m, len(self.path), handlerPath)
+
+ if os.path.isdir(handlerPath):
+ sys.path.insert(0, handlerPath)
+ if os.path.isfile(handlerPath): break
+ if os.path.isdir(handlerPath): break
+
+ if m+1 == len(self.path):
+ pathinfo = ''
+ else:
+ pathinfo = apply(os.path.join, self.path[m+1:])
+
+ if os.path.isdir(handlerPath):
+ modulePath = handlerPath
+ moduleFilename = module + "_index.py"
+ handlerPath = os.path.join(modulePath, moduleFilename)
+ else:
+ modulePath, moduleFilename = os.path.split(handlerPath)
+
+ debug(handlerPath, pathinfo)
+ #warn(handlerPath, pathinfo, modulePath, moduleFilename)
+ #warn("PATH", self.path)
+
+ if not os.path.isfile(handlerPath):
+ self.error(404, handlerPath + " doesn't exist")
+ return 404
+
+ import imp
+
+ moduleName, ext = os.path.splitext(moduleFilename)
+
+ #module = __import__(moduleName)
+ module = __import__("mod.%s.cgibin.%s" % (module, moduleName), {}, {}, (None,))
+
+ os.chdir(modulePath)
+# debug(mod)
+ page = module.run(self.context)
+ page.ncgi.hdf.setValue("CGI.BaseURI", gConfig.gBaseURL)
+
+ if gConfig.gRequireUsername:
+ page.ncgi.hdf.setValue("CGI.Username", username)
+ page.username = username
+
+ if hasattr(page, "checkLoginCookie"):
+ if not page._pageparms.has_key("nologin"):
+ try:
+ page.checkLoginCookie()
+ except CSPage.Redirected:
+ return
+
+ page.ncgi.hdf.setValue("CGI.PathInfo", pathinfo)
+ page.clearPaths()
+ page.setPaths([moduleTemplatePath, systemTemplatePath, systemJLIBPath])
+ ret = page.start()
+
+ try:
+ page.db.close()
+ except AttributeError: pass
+
+ page = None
+
+ return ret
+
+ def error(self, ecode, reason=None):
+ import httpResponses
+ message = httpResponses.gHTTPResponses[ecode]
+
+ template = httpResponses.errorMessage_Default
+ if ecode == 404:
+ template = httpResponses.errorMessage_404
+
+ hdf = neo_util.HDF()
+ hdf.setValue("code", str(ecode))
+ if message: hdf.setValue("message", message)
+ if reason: hdf.setValue("reason", reason)
+
+ for key,val in self.context.environ.items():
+ hdf.setValue("environ." + key, str(val))
+
+ self.context.stdout.write("Content-Type: text/html\r\n")
+ self.context.setStatus(None, ecode)
+ self.context.stdout.write("Status: %s\r\n" % ecode)
+ self.context.stdout.write("\r\n")
+
+ cs = neo_cs.CS(hdf)
+ cs.parseStr(template)
+ page = cs.render()
+
+ self.context.stdout.write(page)
+
+ warn("Error", message, reason)
+
+
+def outputFile(context, fn):
+ fp = open(fn, "rb")
+ data = fp.read()
+ fp.close()
+
+ context.setStatus(None, 200)
+
+ imagetype, encoding = mimetypes.guess_type(fn)
+ debug("imagetype = %s fn = %s" % (imagetype,fn))
+
+ lines = []
+
+ if imagetype:
+ lines.append("Content-Type: %s" % imagetype)
+
+ lines.append("Content-Length: %d" % len(data))
+
+ stat = os.stat(fn)
+ mtime = stat.st_mtime
+ mod_str = time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime(mtime))
+
+ lines.append('Last-Modified: %s GMT' % mod_str)
+
+ expire_time = time.gmtime(time.time() + (360*24*3600))
+ expire_str = time.strftime("%a, %d %b %Y %H:%M:%S", expire_time)
+ lines.append('Expires: %s GMT' % expire_str)
+
+ lines.append("\r\n")
+
+ headers = string.join(lines, "\r\n")
+ context.stdout.write(headers)
+
+ context.stdout.write(data)
+
+ return 200
+
+
+class FakeError:
+ def write(self, s):
+ apache.log_error(s, apache.APLOG_STARTUP)
+
+class ModPythonContext:
+ def __init__ (self, req):
+
+ from mod_python import apache
+
+ self.stdout = apache.CGIStdout(req)
+ self.stdin = apache.CGIStdin(req)
+
+ self.stderr = FakeError()
+ env = apache.build_cgi_env(req)
+
+ self.environ = env
+
+ scriptFilename = self.environ.get("SCRIPT_FILENAME", "")
+ if scriptFilename:
+ path, fn = os.path.split(scriptFilename)
+ os.chdir(path)
+
+ def setStatus(self, request, status):
+ if request:
+ request['status'] = str(status)
+
+
+
+def handler(req):
+ start = time.time()
+
+ from mod_python import apache
+
+ if 1:
+ context = ModPythonContext(req)
+ page = Page(context)
+ page.mod_python_req = req
+
+ gc.enable()
+ ret = page.start()
+ gc.collect()
+
+ ret = apache.OK
+
+ end = time.time()
+ #sys.stderr.write("handler time %s\n" % int((end-start)*1000))
+
+ return ret
+
+
+def main(argv, stdout, environ):
+ context = CSPage.Context()
+ page = Page(context)
+ page.start()
+
+
+if __name__ == "__main__":
+ main(sys.argv, sys.stdout, os.environ)
Property changes on: pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/cgistarter.py
___________________________________________________________________
Added: svn:executable
+ *
Added: pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/fixedpoint.py
===================================================================
--- pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/fixedpoint.py (rev 0)
+++ pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/fixedpoint.py 2009-08-20 21:41:17 UTC (rev 22475)
@@ -0,0 +1,619 @@
+#!/usr/bin/env python
+"""
+FixedPoint objects support decimal arithmetic with a fixed number of
+digits (called the object's precision) after the decimal point. The
+number of digits before the decimal point is variable & unbounded.
+
+The precision is user-settable on a per-object basis when a FixedPoint
+is constructed, and may vary across FixedPoint objects. The precision
+may also be changed after construction via FixedPoint.set_precision(p).
+Note that if the precision of a FixedPoint is reduced via set_precision,
+information may be lost to rounding.
+
+>>> x = FixedPoint("5.55") # precision defaults to 2
+>>> print x
+5.55
+>>> x.set_precision(1) # round to one fraction digit
+>>> print x
+5.6
+>>> print FixedPoint("5.55", 1) # same thing setting to 1 in constructor
+5.6
+>>> repr(x) # returns constructor string that reproduces object exactly
+"FixedPoint('5.6', 1)"
+>>>
+
+When FixedPoint objects of different precision are combined via + - * /,
+the result is computed to the larger of the inputs' precisions, which also
+becomes the precision of the resulting FixedPoint object.
+
+>>> print FixedPoint("3.42") + FixedPoint("100.005", 3)
+103.425
+>>>
+
+When a FixedPoint is combined with other numeric types (ints, floats,
+strings representing a number) via + - * /, then similarly the computati...
[truncated message content] |
|
From: <wgh...@us...> - 2009-08-20 22:04:57
|
Revision: 22478
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=22478&view=rev
Author: wghassan
Date: 2009-08-20 22:04:49 +0000 (Thu, 20 Aug 2009)
Log Message:
-----------
initial checkin of webui
Added Paths:
-----------
pkg/trunk/sandbox/web/webui/
pkg/trunk/sandbox/web/webui/apache.cfg
pkg/trunk/sandbox/web/webui/manifest.xml
pkg/trunk/sandbox/web/webui/src/
pkg/trunk/sandbox/web/webui/src/webui/
pkg/trunk/sandbox/web/webui/src/webui/MBPage.py
pkg/trunk/sandbox/web/webui/src/webui/__init__.py
pkg/trunk/sandbox/web/webui/src/webui/auth/
pkg/trunk/sandbox/web/webui/src/webui/auth/__init__.py
pkg/trunk/sandbox/web/webui/src/webui/auth/browserauth.py
pkg/trunk/sandbox/web/webui/src/webui/auth/cookieauth.py
pkg/trunk/sandbox/web/webui/src/webui/auth/db_auth.py
pkg/trunk/sandbox/web/webui/src/webui/auth/db_queue.py
pkg/trunk/sandbox/web/webui/src/webui/auth/newuser.py
pkg/trunk/sandbox/web/webui/src/webui/auth/nstart.py
pkg/trunk/sandbox/web/webui/src/webui/auth/pwauth.py
pkg/trunk/sandbox/web/webui/src/webui/config.py
pkg/trunk/sandbox/web/webui/src/webui/mod/
pkg/trunk/sandbox/web/webui/src/webui/mod/__init__.py
pkg/trunk/sandbox/web/webui/src/webui/mod/login/
pkg/trunk/sandbox/web/webui/src/webui/mod/login/__init__.py
pkg/trunk/sandbox/web/webui/src/webui/mod/login/cgibin/
pkg/trunk/sandbox/web/webui/src/webui/mod/login/cgibin/__init__.py
pkg/trunk/sandbox/web/webui/src/webui/mod/login/cgibin/changePassword.py
pkg/trunk/sandbox/web/webui/src/webui/mod/login/cgibin/forgotpw.py
pkg/trunk/sandbox/web/webui/src/webui/mod/login/cgibin/register.py
pkg/trunk/sandbox/web/webui/src/webui/mod/login/cgibin/signin.py
pkg/trunk/sandbox/web/webui/src/webui/mod/login/cgibin/signin0.py
pkg/trunk/sandbox/web/webui/src/webui/mod/login/templates/
pkg/trunk/sandbox/web/webui/src/webui/mod/login/templates/changePassword.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/login/templates/forgotpw_1.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/login/templates/forgotpw_3.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/login/templates/register_1.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/login/templates/register_confirm.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/login/templates/signin.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/login/templates/signin0.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/login/templates/welcomeEmail_1.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/__init__.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/__init__.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/admin.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/apps.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/move.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/nodes.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/overview.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/powerboard.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/status.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/tables.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/topic.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/topics.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/webui_index.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/install_app.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/fieldcomplete.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/fieldcomplete2.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/graph.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_graph.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_pb.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/prototype-1.6.0.2.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/prototype.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/scw.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/sorttable.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/x.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/xmlrpc.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/nstart.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/admin.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/apps.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/header.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/header2.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/images/
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/images/rotate.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/includes.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/index.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/move.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/nodes.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/outlets-willow-full-0.025.xml
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/overview.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/powerboard.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/powerboard_status.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/powerboard_status2.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/status.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/style_desktop.css
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/style_phone.css
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/survey/
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/survey/survey.css
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topic.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topics.cs
pkg/trunk/sandbox/web/webui/src/webui/neo_paths.py
pkg/trunk/sandbox/web/webui/src/webui/nstart.py
pkg/trunk/sandbox/web/webui/src/webui/startcgi.py
pkg/trunk/sandbox/web/webui/src/webui/startmod.py
pkg/trunk/sandbox/web/webui/src/webui/xss.py
Added: pkg/trunk/sandbox/web/webui/apache.cfg
===================================================================
--- pkg/trunk/sandbox/web/webui/apache.cfg (rev 0)
+++ pkg/trunk/sandbox/web/webui/apache.cfg 2009-08-20 22:04:49 UTC (rev 22478)
@@ -0,0 +1,10 @@
+
+ SetEnv ROS_ROOT /u/hassan/pr2/ros
+ SetEnv ROS_PACKAGE_PATH /u/hassan/pr2/sros:/u/hassan/pr2/ros-pkg
+ SetEnv ROS_MASTER_URI http://localhost:11311/
+ SetEnv PYTHONPATH /u/hassan/pr2/ros/core/roslib/src:/u/hassan/pr2/sros/pyclearsilver/src
+ SetEnv ROS_BOOST_ROOT /opt/ros
+ SetEnv HOME /tmp
+
+ ScriptAlias /webui "/u/hassan/wgprojects/pr2/sros/webui/webui/startcgi.py"
+
Property changes on: pkg/trunk/sandbox/web/webui/apache.cfg
___________________________________________________________________
Added: svn:executable
+ *
Added: pkg/trunk/sandbox/web/webui/manifest.xml
===================================================================
--- pkg/trunk/sandbox/web/webui/manifest.xml (rev 0)
+++ pkg/trunk/sandbox/web/webui/manifest.xml 2009-08-20 22:04:49 UTC (rev 22478)
@@ -0,0 +1,14 @@
+<package>
+<description brief="PR2 Web UI">
+A web interface to install and launch applications for the PR2.
+</description>
+<author>Scott Hassan/ha...@wi...</author>
+<license>BSD</license>
+<review status="experimental" notes=""/>
+<url>http://pr.willowgarage.com/wiki/iros</url>
+ <depend package="roslib"/>
+ <depend package="rospy"/>
+ <depend package="launchman"/>
+ <depend package="pyclearsilver"/>
+</package>
+
Property changes on: pkg/trunk/sandbox/web/webui/manifest.xml
___________________________________________________________________
Added: svn:executable
+ *
Added: pkg/trunk/sandbox/web/webui/src/webui/MBPage.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/MBPage.py (rev 0)
+++ pkg/trunk/sandbox/web/webui/src/webui/MBPage.py 2009-08-20 22:04:49 UTC (rev 22478)
@@ -0,0 +1,122 @@
+
+from pyclearsilver.CSPage import CSPage
+
+import time
+import string
+import crypt
+import gc
+
+import nstart
+import config
+
+from pyclearsilver.log import *
+
+import neo_cgi
+from pyclearsilver import handle_error
+from auth import db_auth, cookieauth
+
+# 4 hours
+LOGIN_TIMEOUT = 60*60*4
+
+REFRESH_COOKIE_TIMEOUT = 0
+
+class MBPage(CSPage):
+ def subclassinit(self):
+# self._pageparms["nologin"] = 1
+ hdf = self.ncgi.hdf
+# self.setPaths([config.gTemplatePath])
+
+# hdf.setValue("Query.debug", "1")
+# hdf.setValue("Config.DebugPassword","1")
+ hdf.setValue("Config.CompressionEnabled","0")
+ hdf.setValue("Config.WhiteSpaceStrip","0")
+
+ self.login = None
+ self.username = None
+ self.db = None
+ self.userRec = None
+
+ now = int(time.time())
+ today = time.localtime(now)
+ neo_cgi.exportDate(hdf, "CGI.Today", "US/Pacific", now)
+
+ self.authdb = db_auth.initSchema()
+
+ self.getUsername()
+
+ self.setStyleSheet(hdf)
+
+ def setStyleSheet(self, hdf):
+ useragent = hdf.getValue("HTTP.UserAgent", "").lower()
+ if useragent.find("android") != -1 or useragent.find("iphone") != -1:
+ hdf.setValue("CGI.cur.device_style", "style_phone.css")
+ else:
+ hdf.setValue("CGI.cur.device_style", "style_desktop.css")
+
+ def handle_actions2(self):
+ hdf = self.ncgi.hdf
+ hdfobj = hdf.getObj("Query.Action")
+ if hdfobj:
+ self.checkLoginCookie()
+ CSPage.handle_actions(self)
+
+ def getUsername(self):
+ hdf = self.ncgi.hdf
+
+ logincookie = cookieauth.parseLoginCookie(self.ncgi)
+ if logincookie:
+ self.username = logincookie.username
+
+ self.userRec = self.authdb.users.lookup(self.username)
+ hdf.setValue("CGI.Role", self.userRec.role)
+
+ hdf.setValue("CGI.Login", self.username)
+ hdf.setValue("CGI.Login.issued_at", str(logincookie.issued_at))
+ ## set the role for administrators
+# if self.username in ("hassan", "steffi", "keenan", "tashana"):
+# hdf.setValue("CGI.Role", "admin")
+
+ def checkLoginCookie(self):
+ hdf = self.ncgi.hdf
+
+ requestURI = hdf.getValue("CGI.RequestURI", "")
+
+ rurl = config.gBaseURL + "login/signin0.py"
+
+ self.authdb = db_auth.initSchema()
+
+ logincookie = cookieauth.parseLoginCookie(self.ncgi)
+ if not logincookie:
+ self.redirectUri(rurl + "?q=1&request=%s" % neo_cgi.urlEscape(requestURI))
+
+ self.username = logincookie.username
+ userRec = self.authdb.users.lookup(self.username)
+
+ if userRec is None or cookieauth.checkLoginCookie(self.ncgi, logincookie, self.authdb, self.username, userRec) == 0:
+ warn("invalid cookie", rurl + "?q=1&request=%s" % neo_cgi.urlEscape(requestURI))
+ self.redirectUri(rurl + "?q=1&request=%s" % neo_cgi.urlEscape(requestURI))
+ # ----- the cookie is valid!!!! -------
+
+ persist = cookieauth.getPersistCookie(hdf)
+ if persist == 0:
+ # reissue a new cookie with an updated timeout
+ if (time.time() - logincookie.issued_at) > config.REFRESH_COOKIE_TIMEOUT:
+ cookieauth.issueLoginCookie(self.ncgi, self.authdb, self.username, userRec.pw_hash)
+
+ self.login = self.username
+
+ hdf.setValue("CGI.Login", self.username)
+ hdf.setValue("CGI.Login.issued_at", str(logincookie.issued_at))
+
+ def close(self):
+ if hasattr(self, "db") and self.db:
+ self.db.close()
+ self.db = None
+ if hasattr(self, "authdb") and self.authdb:
+ self.authdb.close()
+ self.authdb = None
+
+ def __del__(self):
+ self.close()
+ gc.collect()
+
Added: pkg/trunk/sandbox/web/webui/src/webui/auth/browserauth.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/auth/browserauth.py (rev 0)
+++ pkg/trunk/sandbox/web/webui/src/webui/auth/browserauth.py 2009-08-20 22:04:49 UTC (rev 22478)
@@ -0,0 +1,127 @@
+#! /usr/bin/env python
+
+"""
+usage: %(progname)s [args]
+"""
+
+
+import os, sys, string, time, getopt
+from pyclearsilver.log import *
+
+from pyclearsilver import odb
+
+import config
+
+#import fcrypt as crypt
+import crypt
+
+def _createCheckVal(username, issued_at, pw_hash, vcode):
+ checkval = "%s:%s" % (username, now)
+ realcheckval = "%s:%s:%s" % (checkval, pw_hash, vcode)
+ checkval_hash = crypt.crypt(realcheckval,config.gAuthSalt)
+ return checkval, checkval_hash
+
+
+# -------------------------------
+# issueLoginCookie
+#
+# format: "login:issued_at_time_t:hash(pw_hash+issued_at_time_t)"
+# ex: "V1/jeske:2123123:AS132dd12"
+
+def generateBrowserCookie(authdb, ipaddr):
+ now = int(time.time())
+
+ row = authdb.browserid.newRow()
+ row.creationDate = now
+ row.ipaddr = ipaddr
+ row.save()
+
+ cookie = "V1/%09d" % row.browserid
+
+ return cookie, row.browserid
+
+def issueBrowserCookie(ncgi, authdb, domain):
+ ipaddr = ncgi.hdf.getValue("CGI.RemoteAddress", "")
+
+ bcookie, browserid = generateBrowserCookie(authdb, ipaddr)
+ ncgi.cookieSet("MB_B", bcookie, persist=1, path="/", domain=config.gDomain)
+ return browserid
+
+
+def clearBrowserCookie(ncgi):
+ ncgi.cookieClear("MB_B", "", "/")
+
+def getBrowserCookie(ncgi):
+ bcookie = ncgi.hdf.getValue("Cookie.MB_B","")
+
+ if not bcookie: return None
+
+ version, restCookie = string.split(bcookie, "/", 1)
+ browserid = int(restCookie)
+
+ return browserid
+
+
+def _checkBrowserCookie(authdb, cookie, ipaddr):
+ version, restCookie = string.split(cookie, "/", 1)
+ if version != "V1":
+ warn("browserauth.py", "invalid browser cookie, version", version, cookie)
+ return None
+
+ browserid = int(restCookie)
+
+ try:
+ row = authdb.browserid.fetchRow(("browserid", browserid))
+ except odb.eNoMatchingRows:
+ warn("browserauth.py", "invalid browser cookie, browserid not found")
+ return browserid
+# return None
+
+ if row.ipaddr != ipaddr:
+ warn("browserauth.py", "ipaddr mismatch", row.ipaddr, ipaddr)
+
+ debug("browserauth.py", "cookie", browserid)
+
+ return browserid
+
+def checkBrowserCookie(authdb, ncgi):
+ bcookie = ncgi.hdf.getValue("Cookie.MB_B","")
+ if not bcookie: return None
+
+ ipaddr = ncgi.hdf.getValue("CGI.RemoteAddress", "")
+
+ browserid = _checkBrowserCookie(authdb, bcookie, ipaddr)
+ return browserid
+
+
+
+def test():
+ pass
+
+def usage(progname):
+ print __doc__ % vars()
+
+def main(argv, stdout, environ):
+ progname = argv[0]
+ optlist, args = getopt.getopt(argv[1:], "", ["help", "test", "debug"])
+
+ testflag = 0
+ if len(args) == 0:
+ usage(progname)
+ return
+ for (field, val) in optlist:
+ if field == "--help":
+ usage(progname)
+ return
+ elif field == "--debug":
+ debugfull()
+ elif field == "--test":
+ testflag = 1
+
+ if testflag:
+ test()
+ return
+
+
+if __name__ == "__main__":
+ main(sys.argv, sys.stdout, os.environ)
Added: pkg/trunk/sandbox/web/webui/src/webui/auth/cookieauth.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/auth/cookieauth.py (rev 0)
+++ pkg/trunk/sandbox/web/webui/src/webui/auth/cookieauth.py 2009-08-20 22:04:49 UTC (rev 22478)
@@ -0,0 +1,186 @@
+#! /usr/bin/env python
+
+"""
+usage: %(progname)s [args]
+"""
+
+
+import os, sys, string, time, getopt
+from pyclearsilver.log import *
+
+#import fcrypt as crypt
+import crypt
+
+import config
+
+import browserauth
+
+def _createCheckVal(username, issued_at, pw_hash, vcode):
+ now = int(time.time())
+ checkval = "%s:%s" % (username, now)
+ realcheckval = "%s:%s:%s" % (checkval, pw_hash, vcode)
+ checkval_hash = crypt.crypt(realcheckval,config.gAuthSalt)
+ checkval_hash = checkval_hash[2:]
+ return checkval, checkval_hash
+
+
+# -------------------------------
+# issueLoginCookie
+#
+# format: "login:issued_at_time_t:hash(pw_hash+issued_at_time_t)"
+# ex: "V1/jeske:2123123:AS132dd12"
+
+def generateCookie(username, pw_hash):
+ now = int(time.time())
+ checkval, checkval_hash = _createCheckVal(username, now, pw_hash, config.gAuthVCode)
+ cookie = "V1/%s=%s" % (checkval,checkval_hash)
+
+ return cookie
+
+def getDomain(hdf):
+ hostname = hdf.getValue("HTTP.Host", "")
+ parts = hostname.split(":", 1)
+ hostname = parts[0]
+ if hostname[-1] in string.digits: ## if this is an IP address
+ return hostname
+ parts = string.split(hostname, ".")
+ domain = string.join(parts[1:], ".")
+ return domain
+
+def getPersistCookie(hdf):
+ try:
+ persist = hdf.getIntValue("Cookie.MB_persist", 0)
+ except:
+ persist = 0
+ return persist
+
+def setPersistCookie(ncgi, persist):
+ ncgi.cookieSet("MB_persist", persist, persist=1, domain=config.gDomain)
+
+
+def issueLoginCookie(ncgi, authdb, username, pw_hash, persist=None):
+ if persist == None:
+ persist = getPersistCookie(ncgi.hdf)
+
+ domain = getDomain(ncgi.hdf)
+
+ browserid = browserauth.checkBrowserCookie(authdb, ncgi)
+ if browserid is None:
+ # set the browser cookie
+ browserid = browserauth.issueBrowserCookie(ncgi, authdb, domain)
+
+ debug("cookieauth.py", "BrowserID", browserid)
+ debug("cookieauth.py", "domain", domain)
+
+ if persist == 1:
+ t = time.time()
+ t = t + (86400*14)
+ timestr = time.strftime("%A, %d-%b-%Y %H:%M:%S GMT", time.localtime(t))
+ else:
+ timestr = ""
+
+ cookie = generateCookie(username, pw_hash)
+ ncgi.cookieSet("MB_L1", cookie, persist=persist, path=config.gBaseURL, domain=domain, time_str=timestr)
+
+ #warn("cookieauth.py", "Issued login cookie", username,cookie, domain, timestr, persist)
+
+
+def clearLoginCookie(ncgi, username, domain=None):
+ domain = getDomain(ncgi.hdf)
+ ncgi.cookieClear("MB_L1", "", config.gBaseURL)
+ ncgi.cookieClear("MB_L1", "", "/")
+ if domain:
+ ncgi.cookieClear("MB_L1", domain, config.gBaseURL)
+ ncgi.cookieClear("MB_L1", domain, "/")
+
+
+class LoginCookie:
+ def __init__(self):
+ self.username = None
+ self.issued_at = None
+ self.checkval_hash = None
+ self.cookie = None
+
+def parseLoginCookie(ncgi):
+ cookie = ncgi.hdf.getValue("Cookie.MB_L1","")
+ if not cookie:
+ warn("cookieauth.py", "no cookie!")
+ return 0
+
+ version, restCookie = string.split(cookie, "/", 1)
+ if version != "V1":
+ warn("cookieauth.py", "invalid cookie, version", version, cookie)
+ return 0
+ checkval,checkval_hash = string.split(restCookie,"=", 1)
+ username,issued_at = string.split(checkval,":")
+
+ cookie = LoginCookie()
+ cookie.cookie = cookie
+ cookie.username = username
+ cookie.issued_at = int(issued_at)
+ cookie.checkval_hash = checkval_hash
+
+ return cookie
+
+
+
+def checkLoginCookie(ncgi, logincookie, authdb, username, userRec):
+
+ if username != logincookie.username:
+ warn("cookieauth.py", "invalid cookie, username mismatch", username, logincookie.username)
+ return 0
+
+ persist = getPersistCookie(ncgi.hdf)
+
+ # check for timeout
+ if persist == 0:
+ if (time.time() - logincookie.issued_at) > config.LOGIN_TIMEOUT:
+ warn("cookieauth.py", "invalid cookie, timeout", logincookie.issued_at)
+ return 0
+
+ pw_hash = userRec.pw_hash
+
+ #warn("cookieauth.py", "cookie", username, logincookie.issued_at, pw_hash, logincookie.checkval_hash)
+
+ v_checkval, v_checkval_hash = _createCheckVal(username, logincookie.issued_at, pw_hash, config.gAuthVCode)
+
+ if logincookie.checkval_hash != v_checkval_hash:
+ warn("cookieauth.py", "checkval mismatch", logincookie.checkval_hash, v_checkval_hash)
+
+ return 1
+
+
+
+
+
+
+def test():
+ pass
+
+def usage(progname):
+ print __doc__ % vars()
+
+def main(argv, stdout, environ):
+ progname = argv[0]
+ optlist, args = getopt.getopt(argv[1:], "", ["help", "test", "debug"])
+
+ testflag = 0
+ if len(args) == 0:
+ usage(progname)
+ return
+ for (field, val) in optlist:
+ if field == "--help":
+ usage(progname)
+ return
+ elif field == "--debug":
+ debugfull()
+ elif field == "--test":
+ testflag = 1
+
+ if testflag:
+ test()
+ return
+
+
+if __name__ == "__main__":
+ main(sys.argv, sys.stdout, os.environ)
Added: pkg/trunk/sandbox/web/webui/src/webui/auth/db_auth.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/auth/db_auth.py (rev 0)
+++ pkg/trunk/sandbox/web/webui/src/webui/auth/db_auth.py 2009-08-20 22:04:49 UTC (rev 22478)
@@ -0,0 +1,204 @@
+#! /usr/bin/env python
+
+"""
+usage: %(progname)s [args]
+"""
+
+import nstart
+import os, sys, string, time, getopt
+
+from pyclearsilver.log import *
+
+import config
+
+from pyclearsilver import odb, hdfhelp, odb_sqlite3
+from pyclearsilver import CSPage
+
+from pyclearsilver.odb import *
+
+import pwauth
+
+gDBSubPath = "host"
+gDBFilename = "auth"
+gDBTablePrefix = "auth"
+
+class AuthDB(odb.Database):
+ def __init__(self,db,debug=0):
+ odb.Database.__init__(self, db, debug=debug)
+
+ self.addTable("users", gDBTablePrefix + "_users", UserTable,
+ rowClass=UserRecord)
+ self.addTable("login", gDBTablePrefix + "_login", UserLoginTable)
+ self.addTable("vcode", gDBTablePrefix + "_vcode", VCodeTable)
+ self.addTable("browserid", gDBTablePrefix + "_browserid", BrowserTable)
+
+ def defaultRowClass(self):
+ return hdfhelp.HdfRow
+ def defaultRowListClass(self):
+ return hdfhelp.HdfItemList
+
+ def getAllUsers(self):
+ users = []
+ rows = self.users.fetchAllRows()
+ for row in rows:
+ users.append(row.username)
+
+ return users
+
+
+
+
+class UserTable(odb.Table):
+ def _defineRows(self):
+ self.d_addColumn("uid",kInteger,None,primarykey = 1,
+ autoincrement = 1)
+
+ self.d_addColumn("username",kVarString, indexed=1, unique=1)
+ self.d_addColumn("role", kVarString, default="")
+ self.d_addColumn("pw_hash",kVarString)
+ self.d_addColumn("status",kInteger, default=0)
+ self.d_addColumn("creationDate", kInteger, default=0)
+
+ def lookup(self, username):
+ try:
+ row = self.fetchRow(('username', username))
+ except odb.eNoMatchingRows, reason:
+ row = None
+ return row
+
+ def new(self, username, password):
+ row = self.lookup(username)
+ if row is not None: return row
+
+ row = self.newRow()
+ row.username = username
+ row.creationDate = int(time.time())
+ row.setPassword(password)
+ row.save()
+
+ return row
+
+class UserRecord(hdfhelp.HdfRow):
+ def checkPasswordHash(self, passwordHash):
+ if len(self.pw_hash) < 2: return 0
+ if passwordHash == self.pw_hash: return 1
+ return 0
+
+
+ def checkPassword(self, password):
+ if len(self.pw_hash) < 2: return 0
+
+ return pwauth.checkPassword(password, self.pw_hash)
+
+ def setPassword(self, new_password):
+ self.pw_hash = pwauth.cryptPassword(new_password)
+ self.save()
+
+class UserLoginTable(odb.Table):
+ def _defineRows(self):
+ self.d_addColumn("uid",kInteger, primarykey=1)
+ self.d_addColumn("username",kVarString, indexed=1, primarykey=1)
+ self.d_addColumn("time", kCreatedStampMS, primarykey=1)
+
+ self.d_addColumn("loginType", kInteger)
+ # 0 - incorrect password
+ # 1 - correct password
+
+ self.d_addColumn("browserid",kVarString)
+ self.d_addColumn("ipaddr",kVarString)
+
+
+class VCodeTable(odb.Table):
+ def _defineRows(self):
+ self.d_addColumn("username",kVarString, primarykey=1)
+ self.d_addColumn("vcode",kInteger, default=0)
+ self.d_addColumn("browserid",kInteger, default=0)
+ self.d_addColumn("creationDate", kInteger, default=0)
+
+
+class BrowserTable(odb.Table):
+ def _defineRows(self):
+ self.d_addColumn("browserid",kInteger, primarykey=1, autoincrement=1)
+ self.d_addColumn("ipaddr", kVarString)
+ self.d_addColumn("creationDate", kInteger, default=0)
+
+
+
+def fullDBPath(path_to_store):
+ return os.path.join(path_to_store, gDBFilename + ".db3")
+
+def initSchema(create=0, timeout=None):
+ if timeout is None: timeout = 600
+
+ path = config.getSiteDBPath(gDBSubPath)
+
+ if create == 1:
+ config.createDBPath(path)
+
+ conn = odb_sqlite3.Connection(fullDBPath(path),
+ timeout=timeout)
+
+ db = AuthDB(conn,debug=debug)
+
+ if create:
+ db.createTables()
+ db.synchronizeSchema()
+ db.createIndices()
+
+ if config.gWebUserID is not None and config.gWebGroupID is not None:
+ config.webChown(fullDBPath(path))
+
+ return db
+
+def exists(username):
+ path = config.getSiteDBPath(gDBSubPath)
+ fn = fullDBPath(path)
+ if os.path.exists(fn):
+ return 1
+ return 0
+
+
+def createDB():
+ db = initSchema(create=1)
+ return db
+
+
+def test():
+ db = initSchema()
+
+ rows = db.users.fetchAllRows()
+ for row in rows:
+ print row.username, row.pw_hash
+
+
+
+def usage(progname):
+ print __doc__ % vars()
+
+def main(argv, stdout, environ):
+ progname = argv[0]
+ optlist, args = getopt.getopt(argv[1:], "", ["help", "test", "debug"])
+
+ testflag = 0
+ for (field, val) in optlist:
+ if field == "--help":
+ usage(progname)
+ return
+ elif field == "--debug":
+ debugfull()
+ elif field == "--test":
+ testflag = 1
+
+ if testflag:
+ test()
+ return
+
+ db = initSchema(create=1)
+
+
+
+if __name__ == "__main__":
+ main(sys.argv, sys.stdout, os.environ)
+
+
+
Property changes on: pkg/trunk/sandbox/web/webui/src/webui/auth/db_auth.py
___________________________________________________________________
Added: svn:executable
+ *
Added: pkg/trunk/sandbox/web/webui/src/webui/auth/db_queue.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/auth/db_queue.py (rev 0)
+++ pkg/trunk/sandbox/web/webui/src/webui/auth/db_queue.py 2009-08-20 22:04:49 UTC (rev 22478)
@@ -0,0 +1,144 @@
+#! /usr/bin/env python
+
+"""
+usage: %(progname)s [args]
+"""
+
+import nstart
+import os, sys, string, time, getopt
+
+from pyclearsilver.log import *
+
+import config
+
+from pyclearsilver import odb, hdfhelp, odb_sqlite3
+from pyclearsilver import CSPage
+
+from pyclearsilver.odb import *
+
+gDBPath = "host"
+gDBFilename = "queue"
+gDBTablePrefix = "queue"
+
+class QueueDB(odb.Database):
+ def __init__(self, conn, debug=0):
+ odb.Database.__init__(self, conn, debug=debug)
+
+ self.addTable("queue", gDBTablePrefix + "_queue", QueueTable,
+ rowClass=CommandRecord)
+
+ def defaultRowClass(self):
+ return hdfhelp.HdfRow
+ def defaultRowListClass(self):
+ return hdfhelp.HdfItemList
+
+class QueueTable(odb.Table):
+ def _defineRows(self):
+ self.d_addColumn("qid",kInteger,None,primarykey = 1,
+ autoincrement = 1)
+
+ self.d_addColumn("username",kVarString)
+ self.d_addColumn("cmd",kVarString, indexed=1)
+ self.d_addColumn("data",kVarString)
+ self.d_addColumn("startDate", kInteger, default=0)
+ ## when to activate the command
+
+ def getCommands(self, cmd, when=None):
+ if when:
+ rows = self.fetchRows(('cmd', cmd), where="startDate <= %s" % when)
+ else:
+ rows = self.fetchRows(('cmd', cmd))
+ return rows
+
+ def newCommand(self, username, cmd, startDate, data=""):
+ row = self.newRow()
+ row.username = username
+ row.startDate = startDate
+ row.cmd = cmd
+ row.data = data
+ row.save()
+
+ return row
+
+class CommandRecord(odb.Row):
+ pass
+
+
+def fullDBPath(path_to_store):
+ return os.path.join(path_to_store, gDBFilename + ".db3")
+
+def initSchema(create=0, timeout=None):
+ if timeout is None: timeout = 600
+
+ path = config.getSiteDBPath("host")
+
+ if create == 1:
+ config.createDBPath(path)
+
+ conn = odb_sqlite3.Connection(fullDBPath(path),
+ autocommit=0,
+ timeout=timeout)
+
+ db = QueueDB(conn,debug=debug)
+
+ if create:
+ db.createTables()
+ db.synchronizeSchema()
+ db.createIndices()
+
+ if config.gWebUserID is not None and config.gWebGroupID is not None:
+ config.webChown(fullDBPath(path))
+
+ return db
+
+def exists():
+ path = config.getSiteDBPath("host")
+ fn = fullDBPath(path)
+ if os.path.exists(fn):
+ return 1
+ return 0
+
+
+def createDB():
+ db = initSchema(create=1)
+ return db
+
+
+def test():
+ db = initSchema()
+
+ rows = db.queue.fetchAllRows()
+ for row in rows:
+ print row.username, row.cmd, row.data
+
+
+def usage(progname):
+ print __doc__ % vars()
+
+def main(argv, stdout, environ):
+ progname = argv[0]
+ optlist, args = getopt.getopt(argv[1:], "", ["help", "test", "debug"])
+
+ testflag = 0
+ for (field, val) in optlist:
+ if field == "--help":
+ usage(progname)
+ return
+ elif field == "--debug":
+ debugfull()
+ elif field == "--test":
+ testflag = 1
+
+ if testflag:
+ test()
+ return
+
+ db = initSchema(create=1)
+
+
+
+if __name__ == "__main__":
+ main(sys.argv, sys.stdout, os.environ)
+
+
+
Added: pkg/trunk/sandbox/web/webui/src/webui/auth/newuser.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/auth/newuser.py (rev 0)
+++ pkg/trunk/sandbox/web/webui/src/webui/auth/newuser.py 2009-08-20 22:04:49 UTC (rev 22478)
@@ -0,0 +1,70 @@
+#! /usr/bin/env python
+
+"""
+usage: %(progname)s username
+"""
+
+
+import nstart
+import os, s...
[truncated message content] |
|
From: <wgh...@us...> - 2009-08-24 23:24:21
|
Revision: 22769
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=22769&view=rev
Author: wghassan
Date: 2009-08-24 22:25:19 +0000 (Mon, 24 Aug 2009)
Log Message:
-----------
new status message: AppStatus
Modified Paths:
--------------
pkg/trunk/sandbox/web/launchman/src/launchman.py
pkg/trunk/sandbox/web/launchman/test/pr2_core.app
pkg/trunk/sandbox/web/rosweb2/src/rosweb.py
pkg/trunk/sandbox/web/webui/src/webui/MBPage.py
pkg/trunk/sandbox/web/webui/src/webui/auth/nstart.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/apps.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/apps.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/includes.cs
Modified: pkg/trunk/sandbox/web/launchman/src/launchman.py
===================================================================
--- pkg/trunk/sandbox/web/launchman/src/launchman.py 2009-08-24 22:16:53 UTC (rev 22768)
+++ pkg/trunk/sandbox/web/launchman/src/launchman.py 2009-08-24 22:25:19 UTC (rev 22769)
@@ -54,7 +54,7 @@
class TaskGroup:
def __init__(self, manager):
- self.task = TaskStatus(None, None, None, None, None)
+ self.task = AppUpdate(None, None, None, None, None)
self.app = None
self.runner = None
self.childGroups = []
@@ -76,7 +76,7 @@
loader.load(fn, config)
except:
self.task.status = "error"
- self.manager.pub.publish(self.task)
+ self.manager.app_update.publish(self.task)
return
self.runner = ROSLaunchRunner(rospy.get_param("/run_id"), config, is_core=False)
@@ -104,10 +104,15 @@
class TaskManager:
def __init__(self):
- self.pub = rospy.Publisher("TaskStatus", TaskStatus, self)
+ self.app_update = rospy.Publisher("app_update", AppUpdate, self)
+ self.app_status = rospy.Publisher("app_status", AppStatus, self)
self._taskGroups = {}
self._apps = {}
+ def _send_status(self):
+ apps = self._apps.keys()
+ self.app_status.publish(AppStatus(apps))
+
def start_task(self, req):
a = app.App(req.taskid)
pgroup = None
@@ -141,12 +146,13 @@
group.task.started = rospy.get_rostime()
group.task.status = "starting"
- self.pub.publish(group.task)
+ self.app_update.publish(group.task)
group.launch()
group.task.status = "running"
- self.pub.publish(group.task)
+ self.app_update.publish(group.task)
+ self._send_status()
return StartTaskResponse("done")
@@ -159,7 +165,7 @@
print "_stopTask", group.app.provides
group.task.status = "stopping"
- self.pub.publish(group.task)
+ self.app_update.publish(group.task)
print "childGroups", group, group.childGroups
for cgroup in group.childGroups[:]:
@@ -168,7 +174,7 @@
group.stop()
group.task.status = "stopped"
- self.pub.publish(group.task)
+ self.app_update.publish(group.task)
if group.app.depends:
pgroup = self._taskGroups.get(group.app.depends.strip(), None)
@@ -179,6 +185,7 @@
print "removing", group.app.provides
del self._taskGroups[group.app.provides]
+
def stop_task(self, req):
app = self._apps[req.taskid]
@@ -191,11 +198,14 @@
del self._apps[req.taskid]
+ self._send_status()
+
return StopTaskResponse("done")
def status_update(self, req):
+ self._send_status()
for provides, group in self._taskGroups.items():
- self.pub.publish(group.task)
+ self.app_update.publish(group.task)
return StatusUpdateResponse("done")
Modified: pkg/trunk/sandbox/web/launchman/test/pr2_core.app
===================================================================
--- pkg/trunk/sandbox/web/launchman/test/pr2_core.app 2009-08-24 22:16:53 UTC (rev 22768)
+++ pkg/trunk/sandbox/web/launchman/test/pr2_core.app 2009-08-24 22:25:19 UTC (rev 22769)
@@ -4,4 +4,4 @@
description: Bring up most of the PR2
icon:
provides: pr2_core
-depends: pr2_core
+depends:
Modified: pkg/trunk/sandbox/web/rosweb2/src/rosweb.py
===================================================================
--- pkg/trunk/sandbox/web/rosweb2/src/rosweb.py 2009-08-24 22:16:53 UTC (rev 22768)
+++ pkg/trunk/sandbox/web/rosweb2/src/rosweb.py 2009-08-24 22:25:19 UTC (rev 22769)
@@ -275,7 +275,7 @@
if len(rwttopics) == 0:
logging.warning("no valid topics")
- self.send_response(404)
+ self.send_failure()
return
messages = []
@@ -348,8 +348,8 @@
return 0
return 1
- def send_success(self, buf = "{}", callback = None):
- self.send_response(200)
+ def _send_responsepage(self, retcode=200, buf = "{}", callback = None):
+ self.send_response(retcode)
if callback:
buf = callback + "(" + buf + ");"
self.send_header('Content-Type', 'text/javascript')
@@ -360,6 +360,12 @@
self.wfile.write(buf)
+ def send_success(self, buf = "{}", callback=None):
+ self._send_responsepage(200, buf, callback)
+
+ def send_failure(self, buf = "{}", callback=None):
+ self._send_responsepage(404, buf, callback)
+
def handle_ROS(self, path, qdict):
cstring = self.headers.get('Cookie', '')
@@ -406,7 +412,11 @@
logging.debug("service call: name=%s, args=%s" % (name, args))
rospy.wait_for_service(name)
service_proxy = rospy.ServiceProxy(name, service_class)
- msg = service_proxy(request)
+ try:
+ msg = service_proxy(request)
+ except rospy.ServiceException:
+ self.send_failure()
+ return
msg = rosjson.ros_message_to_json(msg)
logging.debug("service call: name=%s, resp=%s" % (name, msg))
Modified: pkg/trunk/sandbox/web/webui/src/webui/MBPage.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/MBPage.py 2009-08-24 22:16:53 UTC (rev 22768)
+++ pkg/trunk/sandbox/web/webui/src/webui/MBPage.py 2009-08-24 22:25:19 UTC (rev 22769)
@@ -28,8 +28,8 @@
# hdf.setValue("Query.debug", "1")
# hdf.setValue("Config.DebugPassword","1")
- hdf.setValue("Config.CompressionEnabled","0")
- hdf.setValue("Config.WhiteSpaceStrip","0")
+ hdf.setValue("Config.CompressionEnabled","1")
+ hdf.setValue("Config.WhiteSpaceStrip","1")
self.login = None
self.username = None
Modified: pkg/trunk/sandbox/web/webui/src/webui/auth/nstart.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/auth/nstart.py 2009-08-24 22:16:53 UTC (rev 22768)
+++ pkg/trunk/sandbox/web/webui/src/webui/auth/nstart.py 2009-08-24 22:25:19 UTC (rev 22769)
@@ -4,6 +4,9 @@
import os, sys
+PKG = 'webui' # this package name
+import roslib; roslib.load_manifest(PKG)
+
if 1:
script_dir = ''
try:
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/apps.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/apps.py 2009-08-24 22:16:53 UTC (rev 22768)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/apps.py 2009-08-24 22:25:19 UTC (rev 22769)
@@ -30,7 +30,7 @@
aprefix = prefix + ".%d" % i
app.hdfExport(aprefix, hdf)
app.fetchApp(aprefix, hdf)
-
+
def run(context):
return MyPage(context, pagename="apps", nologin=1)
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/apps.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/apps.cs 2009-08-24 22:16:53 UTC (rev 22768)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/apps.cs 2009-08-24 22:25:19 UTC (rev 22769)
@@ -11,7 +11,7 @@
<table align=center cellspacing=5>
<tr>
<?cs each:_app=CGI.cur.apps ?>
- <td class=buttonOff height=100 bgcolor=white objtype="OnOffButtonWidget" topic="/TaskStatus" taskid="<?cs var:_app.taskid ?>"><div valign=top style="height: 70%;"><font color=black><nobr><?cs var:_app.name ?></div><div style="position: relative; bottom: 0px; font-size: 10pt;" objtype=TextWidget topic="/TaskStatus" key=status selector="taskid" selectorValue="<?cs var:_app.taskid?>"> </div></td>
+ <td class=buttonOff height=100 bgcolor=white objtype="OnOffButtonWidget" topic="/app_update" taskid="<?cs var:_app.taskid ?>"><div valign=top style="height: 70%;"><font color=black><nobr><?cs var:_app.name ?></div><div style="position: relative; bottom: 0px; font-size: 10pt;" objtype=TextWidget topic="/app_update" key=status selector="taskid" selectorValue="<?cs var:_app.taskid?>"> </div></td>
<?cs /each ?>
</tr>
</table>
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/includes.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/includes.cs 2009-08-24 22:16:53 UTC (rev 22768)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/includes.cs 2009-08-24 22:25:19 UTC (rev 22769)
@@ -10,9 +10,11 @@
<script type="text/javascript" src="jslib/pr2_pb.js"></script>
<script type="text/javascript" src="jslib/pr2_widgets.js"></script>
+<?cs if:0 ?>
<script type='text/javascript' src='http://www.google.com/jsapi'></script>
<script type='text/javascript'>
google.load("visualization", "1", {packages:["linechart"]});
google.load("visualization", "1", {packages:["gauge"]});
</script>
+<?cs /if ?>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wgh...@us...> - 2009-08-25 01:19:55
|
Revision: 22799
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=22799&view=rev
Author: wghassan
Date: 2009-08-25 01:19:47 +0000 (Tue, 25 Aug 2009)
Log Message:
-----------
added AppStatus and AppUpdate messages
Modified Paths:
--------------
pkg/trunk/sandbox/web/launchman/src/launchman/app.py
pkg/trunk/sandbox/web/launchman/src/launchman.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/header.cs
Added Paths:
-----------
pkg/trunk/sandbox/web/launchman/msg/AppStatus.msg
pkg/trunk/sandbox/web/launchman/msg/AppUpdate.msg
Removed Paths:
-------------
pkg/trunk/sandbox/web/launchman/msg/TaskStatus.msg
Added: pkg/trunk/sandbox/web/launchman/msg/AppStatus.msg
===================================================================
--- pkg/trunk/sandbox/web/launchman/msg/AppStatus.msg (rev 0)
+++ pkg/trunk/sandbox/web/launchman/msg/AppStatus.msg 2009-08-25 01:19:47 UTC (rev 22799)
@@ -0,0 +1 @@
+string[] active
Added: pkg/trunk/sandbox/web/launchman/msg/AppUpdate.msg
===================================================================
--- pkg/trunk/sandbox/web/launchman/msg/AppUpdate.msg (rev 0)
+++ pkg/trunk/sandbox/web/launchman/msg/AppUpdate.msg 2009-08-25 01:19:47 UTC (rev 22799)
@@ -0,0 +1,5 @@
+Header header
+string taskid
+string username
+string status
+time started
Deleted: pkg/trunk/sandbox/web/launchman/msg/TaskStatus.msg
===================================================================
--- pkg/trunk/sandbox/web/launchman/msg/TaskStatus.msg 2009-08-25 01:18:43 UTC (rev 22798)
+++ pkg/trunk/sandbox/web/launchman/msg/TaskStatus.msg 2009-08-25 01:19:47 UTC (rev 22799)
@@ -1,5 +0,0 @@
-Header header
-string taskid
-string username
-string status
-time started
Modified: pkg/trunk/sandbox/web/launchman/src/launchman/app.py
===================================================================
--- pkg/trunk/sandbox/web/launchman/src/launchman/app.py 2009-08-25 01:18:43 UTC (rev 22798)
+++ pkg/trunk/sandbox/web/launchman/src/launchman/app.py 2009-08-25 01:19:47 UTC (rev 22799)
@@ -53,11 +53,12 @@
try:
self.taskid = taskid
self.app_file = app_file
- self.name = doc['name']
- self.package = doc['package']
- self.provides = doc['provides']
- self.launch_file = doc['launch_file']
- self.depends = doc['depends']
+ self.name = doc['name'].strip()
+ self.package = doc['package'].strip()
+ self.launch_file = doc['launch_file'].strip()
+
+ self.provides = doc.get('provides', None)
+ self.depends = doc.get('depends', None)
except KeyError:
print "Invalid YAML file"
Modified: pkg/trunk/sandbox/web/launchman/src/launchman.py
===================================================================
--- pkg/trunk/sandbox/web/launchman/src/launchman.py 2009-08-25 01:18:43 UTC (rev 22798)
+++ pkg/trunk/sandbox/web/launchman/src/launchman.py 2009-08-25 01:19:47 UTC (rev 22799)
@@ -38,6 +38,8 @@
import roslib; roslib.load_manifest(PKG)
+import time
+
from launchman.srv import *
from launchman.msg import *
import rospy
@@ -52,8 +54,14 @@
from launchman import app
-class TaskGroup:
- def __init__(self, manager):
+class AppGroup:
+ def __init__(self, manager, apprunner):
+ self.apprunner = None
+ self.manager = manager
+
+class AppRunner:
+ def __init__(self, taskid, manager):
+ self.taskid = taskid
self.task = AppUpdate(None, None, None, None, None)
self.app = None
self.runner = None
@@ -98,7 +106,7 @@
def __repr__(self):
- return "<TaskGroup %s %s %s>" % (self.app.provides, self.app.taskid, len(self.childGroups))
+ return "<AppRunner %s: %s %s %s>" % (self.taskid, self.app.provides, self.app.taskid, len(self.childGroups))
@@ -116,96 +124,94 @@
def start_task(self, req):
a = app.App(req.taskid)
pgroup = None
- group = self._taskGroups.get(a.provides, None)
- if group:
- if group.task.taskid == req.taskid:
+ runner = self._taskGroups.get(a.provides, None)
+ if runner:
+ if runner.task.taskid == req.taskid:
print "already running"
return StartTaskResponse("already running")
- self._stopTask(group)
+ self._stopTask(runner)
- if a.depends and a.depends.strip():
- print "depends", a.depends
+ if a.depends:
pgroup = self._taskGroups.get(a.depends, None)
if not pgroup:
print "no parent task group %s running." % str(a.depends)
return StartTaskResponse("no parent task group %s running." % str(a.depends))
- self._apps[req.taskid] = a
- group = TaskGroup(self)
- group.app = a
+ runner = AppRunner(req.taskid, self)
+ runner.app = a
+ self._apps[req.taskid] = runner
+
if a.provides:
- self._taskGroups[a.provides] = group
+ self._taskGroups[a.provides] = runner
if pgroup:
- pgroup.childGroups.append(group)
+ pgroup.childGroups.append(runner)
- print "startTask [%s, %s, %s]" % (req.taskid, a.name, req.username)
- group.task.taskid = req.taskid
- group.task.username = req.username
- group.task.started = rospy.get_rostime()
- group.task.status = "starting"
+ #print "startTask [%s, %s, %s]" % (req.taskid, a.name, req.username)
+ runner.task.taskid = req.taskid
+ runner.task.username = req.username
+ runner.task.started = rospy.get_rostime()
+ runner.task.status = "starting"
- self.app_update.publish(group.task)
+ self.app_update.publish(runner.task)
- group.launch()
+ runner.launch()
- group.task.status = "running"
- self.app_update.publish(group.task)
+ time.sleep(1)
+ runner.task.status = "running"
+ self.app_update.publish(runner.task)
self._send_status()
return StartTaskResponse("done")
def showstate(self):
print "_" * 40
- for provides, group in self._taskGroups.items():
- print provides, group.childGroups
+ for provides, runner in self._taskGroups.items():
+ print provides, runner.childGroups
- def _stopTask(self, group):
- print "_stopTask", group.app.provides
+ def _stopTask(self, runner):
+ runner.task.status = "stopping"
+ self.app_update.publish(runner.task)
- group.task.status = "stopping"
- self.app_update.publish(group.task)
-
- print "childGroups", group, group.childGroups
- for cgroup in group.childGroups[:]:
+ for cgroup in runner.childGroups[:]:
self._stopTask(cgroup)
- group.stop()
+ runner.stop()
+ time.sleep(1)
- group.task.status = "stopped"
- self.app_update.publish(group.task)
+ runner.task.status = "stopped"
+ self.app_update.publish(runner.task)
- if group.app.depends:
- pgroup = self._taskGroups.get(group.app.depends.strip(), None)
+ if runner.app.depends:
+ pgroup = self._taskGroups.get(runner.app.depends, None)
if pgroup:
- pgroup.childGroups.remove(group)
+ pgroup.childGroups.remove(runner)
- if group.app.provides:
- print "removing", group.app.provides
- del self._taskGroups[group.app.provides]
+ if runner.app.provides:
+ print "removing", runner.app.provides
+ del self._taskGroups[runner.app.provides]
+ if runner.taskid in self._apps:
+ del self._apps[runner.taskid]
+ print "removing", runner.taskid
+
def stop_task(self, req):
- app = self._apps[req.taskid]
+ if req.taskid not in self._apps:
+ return StopTaskResponse("no such task: %s" % req.taskid)
+
+ runner = self._apps[req.taskid]
- group = self._taskGroups.get(app.provides, None)
- if not group:
- msg = "no such group: " + str(app.provides)
- return StopTaskResponse(msg)
+ self._stopTask(runner)
- self._stopTask(group)
-
- del self._apps[req.taskid]
-
self._send_status()
return StopTaskResponse("done")
def status_update(self, req):
- self._send_status()
- for provides, group in self._taskGroups.items():
- self.app_update.publish(group.task)
+ for provides, runner in self._taskGroups.items():
+ self.app_update.publish(runner.task)
return StatusUpdateResponse("done")
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py 2009-08-25 01:18:43 UTC (rev 22798)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py 2009-08-25 01:19:47 UTC (rev 22799)
@@ -83,8 +83,6 @@
class Application(hdfhelp.HdfRow):
def fetchApp(self, prefix, hdf):
- warn('taskid', self.taskid)
- warn('taskid', repr(self.taskid))
_app = app.App(str(self.taskid))
hdf.setValue(prefix + ".name", _app.name)
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js 2009-08-25 01:18:43 UTC (rev 22798)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js 2009-08-25 01:19:47 UTC (rev 22799)
@@ -62,13 +62,17 @@
}
},
+ receive_service: function(json_result) {
+ // implement this to return the result to the calling service call.
+ },
+
receive: function(json_result) {
try {
+ this.lastTime = json_result.since;
this.evalMessages(json_result);
} catch (e) {
ros_debug("Error with evalMessages.");
}
- this.lastTime = json_result.since;
this.pump();
},
@@ -498,3 +502,32 @@
gRosClasses["RosOut_Widget"] = function(dom){
return new RosOut_Widget(dom);
}
+
+
+
+
+var ActiveTasks = Class.create({
+ initialize: function(domobj) {
+ this.pump = null;
+ this.domobj = domobj;
+ this.topics = [domobj.getAttribute("topic")];
+ },
+
+ init: function() {
+ this.domobj.innerHTML = "";
+ },
+
+ receive: function(msg) {
+ var s = "";
+ for(var i=0; i<msg.active.length; i++) {
+ s = s + "|" + msg.active[i];
+ }
+ this.domobj.innerHTML = s;
+ }
+});
+
+gRosClasses["ActiveTasks"] = function(dom){
+ return new ActiveTasks(dom);
+}
+
+
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/header.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/header.cs 2009-08-25 01:18:43 UTC (rev 22798)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/header.cs 2009-08-25 01:19:47 UTC (rev 22799)
@@ -2,7 +2,10 @@
<tr>
<td width=1%><nobr>Robot: <?cs var:CGI.ServerName?></td>
<td width=1%><img src="templates/images/toolbar/grid-blue-split.gif"></td>
-<td width=90%>Core Status: <font color=green>Running</td>
+<td width=90%><nobr>Core Status: <font color=green>Running</font>
+<span objtype=ActiveTasks topic="/app_status"/>
+</nobr>
+</td>
<td width=1%><img src="templates/images/toolbar/grid-blue-split.gif"></td>
<td width=1%><nobr><div objtype=CircuitMonitor topic="/power_board_state"/></td>
<td width=1%><img src="templates/images/toolbar/grid-blue-split.gif"></td>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wgh...@us...> - 2009-08-25 21:44:23
|
Revision: 22895
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=22895&view=rev
Author: wghassan
Date: 2009-08-25 21:44:13 +0000 (Tue, 25 Aug 2009)
Log Message:
-----------
delay pump by 500ms
Modified Paths:
--------------
pkg/trunk/sandbox/web/launchman/src/launchman.py
pkg/trunk/sandbox/web/rosweb2/src/rosweb.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/apps.cs
Modified: pkg/trunk/sandbox/web/launchman/src/launchman.py
===================================================================
--- pkg/trunk/sandbox/web/launchman/src/launchman.py 2009-08-25 21:24:29 UTC (rev 22894)
+++ pkg/trunk/sandbox/web/launchman/src/launchman.py 2009-08-25 21:44:13 UTC (rev 22895)
@@ -92,7 +92,9 @@
self.runner.launch()
def stop(self):
- if not self.runner: return
+ if not self.runner:
+ print "no runner", self
+ return
self.runner.stop()
self.runner = None
@@ -158,7 +160,6 @@
runner.launch()
- time.sleep(1)
runner.task.status = "running"
self.app_update.publish(runner.task)
self._send_status()
@@ -178,7 +179,6 @@
self._stopTask(cgroup)
runner.stop()
- time.sleep(1)
runner.task.status = "stopped"
self.app_update.publish(runner.task)
Modified: pkg/trunk/sandbox/web/rosweb2/src/rosweb.py
===================================================================
--- pkg/trunk/sandbox/web/rosweb2/src/rosweb.py 2009-08-25 21:24:29 UTC (rev 22894)
+++ pkg/trunk/sandbox/web/rosweb2/src/rosweb.py 2009-08-25 21:44:13 UTC (rev 22895)
@@ -159,7 +159,12 @@
msg_class = roslib.scriptutil.get_message_class(topic_type)
- self.sub = rospy.Subscriber(self.topic, msg_class, self.topic_callback)
+ #print "RosWebtopic", self.topic, msg_class
+ try:
+ self.sub = rospy.Subscriber(self.topic, msg_class, self.topic_callback)
+ except:
+ print self.topic, msg_class
+ raise
self.initialized = True
except ROSWebException:
raise
@@ -178,6 +183,7 @@
def topic_callback(self, data):
try:
self.factory.cond.acquire()
+
self.messages.append((self.factory.counter, data))
self.factory.counter = self.factory.counter + 1
self.messages = self.messages[-20:]
@@ -236,6 +242,7 @@
def callback(self, data):
try:
self.factory.cond.acquire()
+
self.messages.append((self.factory.counter, data))
self.factory.counter = self.factory.counter + 1
self.messages = self.messages[-3:]
@@ -311,7 +318,7 @@
lastSince = max(t, lastSince)
finally:
self.server.factory.cond.release()
-
+
buf = cStringIO.StringIO()
buf.write("{")
buf.write('"since": %s,' % lastSince)
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js 2009-08-25 21:24:29 UTC (rev 22894)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js 2009-08-25 21:44:13 UTC (rev 22895)
@@ -73,7 +73,7 @@
} catch (e) {
ros_debug("Error with evalMessages.");
}
- this.pump();
+ setTimeout("gPump.pump();", 500);
},
evalMessages: function(json_result) {
@@ -208,7 +208,7 @@
this.domobj.setAttribute("class", "buttonOff");
}
- this.pump.service_call("status_update", []);
+ //this.pump.service_call("status_update", []);
},
receive: function(msg) {
@@ -430,7 +430,7 @@
initialize: function(domobj) {
this.pump = null;
this.domobj = domobj;
- this.topics = ['/rosout_agg'];
+ this.topics = ['/rosout'];
this.maxlines = parseInt(domobj.getAttribute("maxlines", "100"));
this.tbl = null;
@@ -454,7 +454,7 @@
var c, tn;
c = row.insertCell(0);
c.className = "rosout";
- c.style.width = "2%";
+ c.style.width = "5%";
var level = "";
if(msg.level == "16") level="Fatal";
if(msg.level == "8") level="Error";
@@ -466,16 +466,16 @@
c = row.insertCell(1);
c.className = "rosout";
- c.style.width = "90%";
+ c.style.width = "80%";
tn = document.createTextNode(msg.msg);
c.appendChild(tn);
- // c = row.insertCell(2);
- // c.style.width = "10%";
- // c.className = "rosout";
- // tn = document.createTextNode(msg.name);
- // c.appendChild(tn);
+ c = row.insertCell(2);
+ c.style.width = "15%";
+ c.className = "rosout";
+ tn = document.createTextNode(msg.name);
+ c.appendChild(tn);
// c = row.insertCell(3);
// c.style.width = "5%";
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/apps.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/apps.cs 2009-08-25 21:24:29 UTC (rev 22894)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/apps.cs 2009-08-25 21:44:13 UTC (rev 22895)
@@ -21,8 +21,9 @@
<tr>
<td width=100%>
<table class=rosout><tr>
-<td class=rosoutHeading style="width: 1%;">Severity</td>
-<td class=rosoutHeading style="width: 90%;">Message</td>
+<td class=rosoutHeading style="width: 5%;">Severity</td>
+<td class=rosoutHeading style="width: 80%;">Message</td>
+<td class=rosoutHeading style="width: 15%;">Node</td>
</table>
<div style="border: 2px solid white; height: 30em; width: 80%;" objtype=RosOut_Widget></div><br>
</td>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rob...@us...> - 2009-08-25 23:41:50
|
Revision: 22916
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=22916&view=rev
Author: rob_wheeler
Date: 2009-08-25 23:41:42 +0000 (Tue, 25 Aug 2009)
Log Message:
-----------
A rosweb plugin that serves tiles from the map_server as JPEG images
Added Paths:
-----------
pkg/trunk/sandbox/web/map_tiler/
pkg/trunk/sandbox/web/map_tiler/manifest.xml
pkg/trunk/sandbox/web/map_tiler/src/
pkg/trunk/sandbox/web/map_tiler/src/map_tiler/
pkg/trunk/sandbox/web/map_tiler/src/map_tiler/__init__.py
pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py
Added: pkg/trunk/sandbox/web/map_tiler/manifest.xml
===================================================================
--- pkg/trunk/sandbox/web/map_tiler/manifest.xml (rev 0)
+++ pkg/trunk/sandbox/web/map_tiler/manifest.xml 2009-08-25 23:41:42 UTC (rev 22916)
@@ -0,0 +1,19 @@
+<package>
+ <description brief="map_tiler">
+
+ rosweb plugin to serve map tiles as jpeg
+
+ </description>
+ <author>Rob Wheeler</author>
+ <license>BSD</license>
+ <review status="unreviewed" notes=""/>
+ <url>http://pr.willowgarage.com/wiki/map_tiler</url>
+ <depend package="rosweb2"/>
+ <depend package="nav_msgs"/>
+ <export>
+ <rosweb2 plugin="map_tiler.handler"/>
+ </export>
+
+</package>
+
+
Added: pkg/trunk/sandbox/web/map_tiler/src/map_tiler/__init__.py
===================================================================
--- pkg/trunk/sandbox/web/map_tiler/src/map_tiler/__init__.py (rev 0)
+++ pkg/trunk/sandbox/web/map_tiler/src/map_tiler/__init__.py 2009-08-25 23:41:42 UTC (rev 22916)
@@ -0,0 +1 @@
+import map_tiler.handler
Added: pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py
===================================================================
--- pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py (rev 0)
+++ pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py 2009-08-25 23:41:42 UTC (rev 22916)
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+import rospy
+import rosservice
+import Image
+import cStringIO
+import time
+
+_map_cache = {}
+_scale_cache = {}
+
+def config_plugin():
+ return [{'url': '/map', 'handler': map_tiler_handler}]
+
+def map_tiler_handler(self, path, qdict):
+ service_name = qdict.get('service', ['static_map'])[0]
+ scale = float(qdict.get('scale', [1])[0])
+ x = int(qdict.get('x', [0])[0])
+ y = int(qdict.get('y', [0])[0])
+ width = int(qdict.get('width', [256])[0])
+ height = int(qdict.get('height', [256])[0])
+ map_key = service_name
+ scale_key = '%s:%s' % (service_name, scale)
+ start_time = time.time()
+ try:
+ im = _scale_cache[scale_key]
+ except KeyError:
+ try:
+ im = _map_cache[map_key]
+ except KeyError:
+ rospy.wait_for_service(service_name)
+ service_class = rosservice.get_service_class_by_name('/' + service_name)
+ service_proxy = rospy.ServiceProxy(service_name, service_class)
+ resp = service_proxy()
+ size = (resp.map.info.width, resp.map.info.height)
+ im = Image.frombuffer('L', size, resp.map.data, "raw", 'L', 0, -1)
+ remap = {0:255, 100: 0, 255:128}
+ im = im.point(lambda x: remap.get(x, 0))
+ _map_cache[map_key] = im
+ if scale != 1:
+ size = im.size
+ im = im.resize((int(size[0] / scale), int(size[1] / scale)), Image.BICUBIC)
+ _scale_cache[scale_key] = im
+
+ im = im.crop((x, y, x + width, y + height))
+ buf = cStringIO.StringIO()
+ im.save(buf, format='JPEG')
+ jpeg = buf.getvalue()
+ self.send_response(200)
+ self.send_header('Content-Type', 'image/jpeg')
+ self.send_header('Content-Length', str(len(jpeg)))
+ self.end_headers()
+ self.wfile.write(jpeg)
+ print " Overall time: %f\n" % (time.time() - start_time)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wgh...@us...> - 2009-08-26 04:15:08
|
Revision: 22943
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=22943&view=rev
Author: wghassan
Date: 2009-08-26 04:14:59 +0000 (Wed, 26 Aug 2009)
Log Message:
-----------
changed the app loading
Modified Paths:
--------------
pkg/trunk/sandbox/web/launchman/src/launchman/app.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py
Modified: pkg/trunk/sandbox/web/launchman/src/launchman/app.py
===================================================================
--- pkg/trunk/sandbox/web/launchman/src/launchman/app.py 2009-08-26 04:05:27 UTC (rev 22942)
+++ pkg/trunk/sandbox/web/launchman/src/launchman/app.py 2009-08-26 04:14:59 UTC (rev 22943)
@@ -44,21 +44,33 @@
return pkgpath
class App:
+ app_keys = ('name', 'package', 'launch_file', 'description',
+ 'icon', 'provides', 'depends')
def __init__(self, taskid):
+ self.taskid = taskid
+ self.package, self.app_file = self.taskid.split('/', 1)
+ self.path = None
+
+ def fn(self):
+ if self.path: return self.path
+ self.path = getPackagePath(self.package)
+ fn = os.path.join(self.path, self.app_file)
+ return fn
+
+ def load_yaml(self):
+ fn = self.fn()
# TODO catch file system exception
- package, app_file = taskid.split('/', 1)
- sys.stderr.write(package + "\n")
- path = getPackagePath(package)
- doc = yaml.load(open(os.path.join(path, app_file)))
+ doc = yaml.load(open(fn))
+ return doc
+
+ def load(self):
+ doc = self.load_yaml()
try:
- self.taskid = taskid
- self.app_file = app_file
- self.name = doc['name'].strip()
- self.package = doc['package'].strip()
- self.launch_file = doc['launch_file'].strip()
-
- self.provides = doc.get('provides', None)
- self.depends = doc.get('depends', None)
+ for key in self.app_keys:
+ if doc.has_key(key):
+ val = doc[key]
+ if val is not None: val = val.strip()
+ setattr(self, key, val)
except KeyError:
print "Invalid YAML file"
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py 2009-08-26 04:05:27 UTC (rev 22942)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py 2009-08-26 04:14:59 UTC (rev 22943)
@@ -84,8 +84,13 @@
class Application(hdfhelp.HdfRow):
def fetchApp(self, prefix, hdf):
_app = app.App(str(self.taskid))
-
- hdf.setValue(prefix + ".name", _app.name)
+ doc = _app.load_yaml()
+
+ for key, val in doc.items():
+ if val is not None:
+ hdf.setValue(prefix + "." + key, val)
+ else:
+ hdf.setValue(prefix + "." + key, '')
def fullDBPath(path_to_store):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wgh...@us...> - 2009-08-26 05:33:26
|
Revision: 22954
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=22954&view=rev
Author: wghassan
Date: 2009-08-26 05:33:18 +0000 (Wed, 26 Aug 2009)
Log Message:
-----------
updated to handle mod-python
Modified Paths:
--------------
pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/cgistarter.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
pkg/trunk/sandbox/web/webui/src/webui/startmod.py
Modified: pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/cgistarter.py
===================================================================
--- pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/cgistarter.py 2009-08-26 05:16:49 UTC (rev 22953)
+++ pkg/trunk/sandbox/web/pyclearsilver/src/pyclearsilver/cgistarter.py 2009-08-26 05:33:18 UTC (rev 22954)
@@ -111,11 +111,8 @@
return outputFile(self.context, fn)
## manage the Python module Path
-# sys.path.insert(0, os.path.join(cwd, "pysrc"))
-# sys.path.insert(0, os.path.join(cwd, "pysrc", "base"))
-
+ sys.path.insert(0, os.path.abspath(cwd))
sys.path.insert(0, os.path.abspath(moduleRootPath))
- #sys.path.insert(0, os.path.abspath(handlerRoot))
debug("sys.path", sys.path)
@@ -146,7 +143,7 @@
modulePath, moduleFilename = os.path.split(handlerPath)
debug(handlerPath, pathinfo)
- #warn(handlerPath, pathinfo, modulePath, moduleFilename)
+ #warn("PATH", handlerPath, pathinfo, modulePath, moduleFilename)
#warn("PATH", self.path)
if not os.path.isfile(handlerPath):
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js 2009-08-26 05:16:49 UTC (rev 22953)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js 2009-08-26 05:33:18 UTC (rev 22954)
@@ -182,8 +182,8 @@
gPump = new MessagePump("http://" + window.location.hostname + ":8080" + prefix);
gPump.setupWidgets();
- setTimeout("gPump.pump();", 1000);
- // gPump.pump();
+ //setTimeout("gPump.pump();", 10);
+ gPump.pump();
}
// *******************************************
Modified: pkg/trunk/sandbox/web/webui/src/webui/startmod.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/startmod.py 2009-08-26 05:16:49 UTC (rev 22953)
+++ pkg/trunk/sandbox/web/webui/src/webui/startmod.py 2009-08-26 05:33:18 UTC (rev 22954)
@@ -2,11 +2,13 @@
import os, sys
-sys.path.insert(0, "/u/hassan/pr2/ros/core/roslib/src")
+rosroot = '/u/hassan/pr2/ros'
+sys.path.insert(0, os.path.join(rosroot, "core/roslib/src"))
-os.environ['ROS_ROOT'] = '/u/hassan/pr2/ros'
+os.environ['ROS_ROOT'] = rosroot
os.environ['ROS_PACKAGE_PATH'] = '/u/hassan/pr2/ros-pkg'
os.environ['ROS_MASTER_URI'] = 'http://localhost:11311/'
+os.environ['PATH'] = os.path.join(rosroot, "bin") + ":" + os.environ.get('PATH', "")
os.environ['HOME'] = '/tmp'
PKG = 'webui' # this package name
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wgh...@us...> - 2009-08-26 18:59:40
|
Revision: 23000
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=23000&view=rev
Author: wghassan
Date: 2009-08-26 18:59:29 +0000 (Wed, 26 Aug 2009)
Log Message:
-----------
turn roslib caching to 1 hour and catch broken pipe exceptions
Modified Paths:
--------------
pkg/trunk/sandbox/web/rosweb2/src/rosweb.py
pkg/trunk/sandbox/web/webui/src/webui/startcgi.py
pkg/trunk/sandbox/web/webui/src/webui/startmod.py
Modified: pkg/trunk/sandbox/web/rosweb2/src/rosweb.py
===================================================================
--- pkg/trunk/sandbox/web/rosweb2/src/rosweb.py 2009-08-26 18:59:18 UTC (rev 22999)
+++ pkg/trunk/sandbox/web/rosweb2/src/rosweb.py 2009-08-26 18:59:29 UTC (rev 23000)
@@ -356,17 +356,24 @@
return 1
def _send_responsepage(self, retcode=200, buf = "{}", callback = None):
- self.send_response(retcode)
- if callback:
- buf = callback + "(" + buf + ");"
- self.send_header('Content-Type', 'text/javascript')
- else:
- self.send_header('Content-Type', 'application/json')
- self.send_header('Content-Length', str(len(buf)))
- self.end_headers()
-
- self.wfile.write(buf)
+ try:
+ self.send_response(retcode)
+ if callback:
+ buf = callback + "(" + buf + ");"
+ self.send_header('Content-Type', 'text/javascript')
+ else:
+ self.send_header('Content-Type', 'application/json')
+ self.send_header('Content-Length', str(len(buf)))
+ self.end_headers()
+ self.wfile.write(buf)
+ except socket.error, (ecode, reason):
+ if ecode == 32:
+ print ecode, reason
+ else:
+ raise
+
+
def send_success(self, buf = "{}", callback=None):
self._send_responsepage(200, buf, callback)
Modified: pkg/trunk/sandbox/web/webui/src/webui/startcgi.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/startcgi.py 2009-08-26 18:59:18 UTC (rev 22999)
+++ pkg/trunk/sandbox/web/webui/src/webui/startcgi.py 2009-08-26 18:59:29 UTC (rev 23000)
@@ -19,6 +19,7 @@
os.environ['HOME'] = '/tmp'
+os.environ['ROS_CACHE_TIMEOUT'] = '3600'
PKG = 'webui' # this package name
import roslib; roslib.load_manifest(PKG)
ros_root = os.environ['ROS_ROOT']
Modified: pkg/trunk/sandbox/web/webui/src/webui/startmod.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/startmod.py 2009-08-26 18:59:18 UTC (rev 22999)
+++ pkg/trunk/sandbox/web/webui/src/webui/startmod.py 2009-08-26 18:59:29 UTC (rev 23000)
@@ -9,8 +9,10 @@
os.environ['ROS_PACKAGE_PATH'] = '/u/hassan/pr2/ros-pkg'
os.environ['ROS_MASTER_URI'] = 'http://localhost:11311/'
os.environ['PATH'] = os.path.join(rosroot, "bin") + ":" + os.environ.get('PATH', "")
+os.environ['ROS_BOOST_PATH'] = '/opt/ros/'
os.environ['HOME'] = '/tmp'
+os.environ['ROS_CACHE_TIMEOUT'] = '3600'
PKG = 'webui' # this package name
import roslib; roslib.load_manifest(PKG)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wgh...@us...> - 2009-08-27 05:37:41
|
Revision: 23108
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=23108&view=rev
Author: wghassan
Date: 2009-08-27 05:37:29 +0000 (Thu, 27 Aug 2009)
Log Message:
-----------
added support to applications
Modified Paths:
--------------
pkg/trunk/sandbox/web/launchman/msg/AppStatus.msg
pkg/trunk/sandbox/web/launchman/src/launchman.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_widgets.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros_toolbar.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/apps.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/header.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/includes.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/status.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/style_desktop.css
pkg/trunk/sandbox/web/webui/src/webui/startcgi.py
pkg/trunk/sandbox/web/webui/src/webui/startmod.py
Added Paths:
-----------
pkg/trunk/sandbox/web/launchman/msg/Application.msg
pkg/trunk/sandbox/web/sample_application/
pkg/trunk/sandbox/web/sample_application/README
pkg/trunk/sandbox/web/sample_application/cgibin/
pkg/trunk/sandbox/web/sample_application/cgibin/__init__.py
pkg/trunk/sandbox/web/sample_application/cgibin/sample_application_index.py
pkg/trunk/sandbox/web/sample_application/images/
pkg/trunk/sandbox/web/sample_application/images/screenshot.png
pkg/trunk/sandbox/web/sample_application/jslib/
pkg/trunk/sandbox/web/sample_application/listener
pkg/trunk/sandbox/web/sample_application/listener.py
pkg/trunk/sandbox/web/sample_application/manifest.xml
pkg/trunk/sandbox/web/sample_application/sample_app.app
pkg/trunk/sandbox/web/sample_application/talker
pkg/trunk/sandbox/web/sample_application/talker.py
pkg/trunk/sandbox/web/sample_application/talker_listener.launch
pkg/trunk/sandbox/web/sample_application/templates/
pkg/trunk/sandbox/web/sample_application/templates/index.cs
pkg/trunk/sandbox/web/webui/src/webui/cgistarter.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/appcon.py
Removed Paths:
-------------
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/install_app.py
Modified: pkg/trunk/sandbox/web/launchman/msg/AppStatus.msg
===================================================================
--- pkg/trunk/sandbox/web/launchman/msg/AppStatus.msg 2009-08-27 05:09:26 UTC (rev 23107)
+++ pkg/trunk/sandbox/web/launchman/msg/AppStatus.msg 2009-08-27 05:37:29 UTC (rev 23108)
@@ -1 +1 @@
-string[] active
+Application[] active
Added: pkg/trunk/sandbox/web/launchman/msg/Application.msg
===================================================================
--- pkg/trunk/sandbox/web/launchman/msg/Application.msg (rev 0)
+++ pkg/trunk/sandbox/web/launchman/msg/Application.msg 2009-08-27 05:37:29 UTC (rev 23108)
@@ -0,0 +1,3 @@
+string taskid
+string name
+string status
Modified: pkg/trunk/sandbox/web/launchman/src/launchman.py
===================================================================
--- pkg/trunk/sandbox/web/launchman/src/launchman.py 2009-08-27 05:09:26 UTC (rev 23107)
+++ pkg/trunk/sandbox/web/launchman/src/launchman.py 2009-08-27 05:37:29 UTC (rev 23108)
@@ -127,12 +127,14 @@
self._apps = {}
def _send_status(self):
- apps = self._apps.keys()
- self.app_status.publish(AppStatus(apps))
+ apps = []
+ for taskid, runner in self._apps.items():
+ apps.append(Application(taskid, runner.app.name, runner.task.status))
+ self.app_status.publish(apps)
def start_task(self, req):
a = app.App(req.taskid)
- a.load_yaml()
+ a.load()
pgroup = None
runner = self._taskGroups.get(a.provides, None)
Added: pkg/trunk/sandbox/web/sample_application/README
===================================================================
--- pkg/trunk/sandbox/web/sample_application/README (rev 0)
+++ pkg/trunk/sandbox/web/sample_application/README 2009-08-27 05:37:29 UTC (rev 23108)
@@ -0,0 +1,3 @@
+This is the simplest rospy demo: a talker node that publishes
+std_msgs/String to the /chatter topic and a listener node that subscribes
+to these messages.
Added: pkg/trunk/sandbox/web/sample_application/cgibin/sample_application_index.py
===================================================================
--- pkg/trunk/sandbox/web/sample_application/cgibin/sample_application_index.py (rev 0)
+++ pkg/trunk/sandbox/web/sample_application/cgibin/sample_application_index.py 2009-08-27 05:37:29 UTC (rev 23108)
@@ -0,0 +1,30 @@
+#! /usr/bin/env python
+
+"""
+usage: %(progname)s [args]
+"""
+
+import os, sys, string, time, getopt, re
+import neo_cgi, neo_util, neo_cs
+from pyclearsilver.log import *
+from pyclearsilver import CSPage, odb
+
+from webui import MBPage
+
+class MyPage(MBPage.MBPage):
+ def setup(self, hdf):
+ pass
+
+ def display(self, hdf):
+ pass
+
+
+def run(context):
+ return MyPage(context, pagename="index", nologin=1)
+
+def main():
+ context = CSPage.Context()
+ run(context).start()
+
+if __name__ == "__main__":
+ main()
Property changes on: pkg/trunk/sandbox/web/sample_application/cgibin/sample_application_index.py
___________________________________________________________________
Added: svn:executable
+ *
Added: pkg/trunk/sandbox/web/sample_application/images/screenshot.png
===================================================================
(Binary files differ)
Property changes on: pkg/trunk/sandbox/web/sample_application/images/screenshot.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: pkg/trunk/sandbox/web/sample_application/listener
===================================================================
--- pkg/trunk/sandbox/web/sample_application/listener (rev 0)
+++ pkg/trunk/sandbox/web/sample_application/listener 2009-08-27 05:37:29 UTC (rev 23108)
@@ -0,0 +1 @@
+link listener.py
\ No newline at end of file
Property changes on: pkg/trunk/sandbox/web/sample_application/listener
___________________________________________________________________
Added: svn:special
+ *
Added: pkg/trunk/sandbox/web/sample_application/listener.py
===================================================================
--- pkg/trunk/sandbox/web/sample_application/listener.py (rev 0)
+++ pkg/trunk/sandbox/web/sample_application/listener.py 2009-08-27 05:37:29 UTC (rev 23108)
@@ -0,0 +1,63 @@
+#!/usr/bin/env python
+# Software License Agreement (BSD License)
+#
+# Copyright (c) 2008, Willow Garage, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+# * Neither the name of Willow Garage, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# Revision $Id: listener.py 5263 2009-07-17 23:30:38Z sfkwc $
+
+## Simple talker demo that listens to std_msgs/Strings published
+## to the 'chatter' topic
+
+PKG = 'rospy_tutorials' # this package name
+import roslib; roslib.load_manifest(PKG)
+
+import rospy
+from std_msgs.msg import String
+
+def callback(data):
+ rospy.loginfo(rospy.get_caller_id()+"I heard %s",data.data)
+
+def listener():
+
+ # in ROS, nodes are unique named. If two nodes with the same
+ # node are launched, the previous one is kicked off. The
+ # anonymous=True flag means that rospy will choose a unique
+ # name for our 'talker' node so that multiple talkers can
+ # run simultaenously.
+ rospy.init_node('listener', anonymous=True)
+
+ rospy.Subscriber("chatter", String, callback)
+
+ # spin() simply keeps python from exiting until this node is stopped
+ rospy.spin()
+
+if __name__ == '__main__':
+ listener()
Property changes on: pkg/trunk/sandbox/web/sample_application/listener.py
___________________________________________________________________
Added: svn:executable
+ *
Added: pkg/trunk/sandbox/web/sample_application/manifest.xml
===================================================================
--- pkg/trunk/sandbox/web/sample_application/manifest.xml (rev 0)
+++ pkg/trunk/sandbox/web/sample_application/manifest.xml 2009-08-27 05:37:29 UTC (rev 23108)
@@ -0,0 +1,14 @@
+<package>
+ <description brief="sample_app">
+ Sample Application
+ </description>
+ <author>Scott Hassan</author>
+ <license>BSD</license>
+ <review status="unreviewed" notes=""/>
+ <url>http://pr.willowgarage.com/wiki/sample_app</url>
+ <depend package="roslib"/>
+ <depend package="rospy"/>
+ <depend package="webui"/>
+</package>
+
+
Added: pkg/trunk/sandbox/web/sample_application/sample_app.app
===================================================================
--- pkg/trunk/sandbox/web/sample_application/sample_app.app (rev 0)
+++ pkg/trunk/sandbox/web/sample_application/sample_app.app 2009-08-27 05:37:29 UTC (rev 23108)
@@ -0,0 +1,7 @@
+name: Sample App
+package: sample_application
+launch_file: talker_listener.launch
+description: A sample ROS app to show the structure of an complete application. It shows how to build a webui and register a plugin.
+icon: images/screenshot.png
+provides:
+depends:
Added: pkg/trunk/sandbox/web/sample_application/talker
===================================================================
--- pkg/trunk/sandbox/web/sample_application/talker (rev 0)
+++ pkg/trunk/sandbox/web/sample_application/talker 2009-08-27 05:37:29 UTC (rev 23108)
@@ -0,0 +1 @@
+link talker.py
\ No newline at end of file
Property changes on: pkg/trunk/sandbox/web/sample_application/talker
___________________________________________________________________
Added: svn:special
+ *
Added: pkg/trunk/sandbox/web/sample_application/talker.py
===================================================================
--- pkg/trunk/sandbox/web/sample_application/talker.py (rev 0)
+++ pkg/trunk/sandbox/web/sample_application/talker.py 2009-08-27 05:37:29 UTC (rev 23108)
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+# Software License Agreement (BSD License)
+#
+# Copyright (c) 2008, Willow Garage, Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+# * Neither the name of Willow Garage, Inc. nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# Revision $Id: talker.py 5263 2009-07-17 23:30:38Z sfkwc $
+
+## Simple talker demo that published std_msgs/Strings messages
+## to the 'chatter' topic
+
+import roslib; roslib.load_manifest('rospy_tutorials')
+
+import rospy
+from std_msgs.msg import String
+
+def talker():
+ pub = rospy.Publisher('chatter', String)
+ rospy.init_node('talker', anonymous=True)
+ r = rospy.Rate(1) # 10hz
+ while not rospy.is_shutdown():
+ str = "hello world %s"%rospy.get_time()
+ rospy.loginfo(str)
+ pub.publish(str)
+ r.sleep()
+
+if __name__ == '__main__':
+ try:
+ talker()
+ except rospy.ROSInterruptException: pass
Property changes on: pkg/trunk/sandbox/web/sample_application/talker.py
___________________________________________________________________
Added: svn:executable
+ *
Added: pkg/trunk/sandbox/web/sample_application/talker_listener.launch
===================================================================
--- pkg/trunk/sandbox/web/sample_application/talker_listener.launch (rev 0)
+++ pkg/trunk/sandbox/web/sample_application/talker_listener.launch 2009-08-27 05:37:29 UTC (rev 23108)
@@ -0,0 +1,4 @@
+<launch>
+ <node pkg="sample_application" type="listener.py"/>
+ <node pkg="sample_application" type="talker.py"/>
+</launch>
Added: pkg/trunk/sandbox/web/sample_application/templates/index.cs
===================================================================
--- pkg/trunk/sandbox/web/sample_application/templates/index.cs (rev 0)
+++ pkg/trunk/sandbox/web/sample_application/templates/index.cs 2009-08-27 05:37:29 UTC (rev 23108)
@@ -0,0 +1,27 @@
+<html>
+<head>
+<?cs include:"includes.cs" ?>
+</head>
+
+<body onload="ros_handleOnLoad('/ros')">
+<?cs include:"header.cs" ?>
+<h3>Sample Application</h3>
+
+<table align=right>
+<td>
+<input class=app_button type=button value="" objtype="LaunchButtonWidget2" topic="/app_update" taskid="<?cs var:CGI.cur.app.taskid ?>">
+<div class=app_status objtype=TextWidget topic="/app_update" key=status selector="taskid" selectorValue="<?cs var:CGI.cur.app.taskid?>"> </div>
+</td>
+</table>
+
+<table width=80% align=center>
+<tr>
+<td>
+<div style="align: center; border: 1px solid black; font-size: 10pt; font-family: courier; height: 40em; width: 60em;" objtype=ScrollingTextWidget topic="/chatter"></div><br>
+</td>
+</table>
+
+<div id=ErrorDiv></div>
+
+</body>
+</html>
Property changes on: pkg/trunk/sandbox/web/sample_application/templates/index.cs
___________________________________________________________________
Added: svn:executable
+ *
Added: pkg/trunk/sandbox/web/webui/src/webui/cgistarter.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/cgistarter.py (rev 0)
+++ pkg/trunk/sandbox/web/webui/src/webui/cgistarter.py 2009-08-27 05:37:29 UTC (rev 23108)
@@ -0,0 +1,342 @@
+#! /usr/bin/env python
+
+import os, sys, string, time, string
+from pyclearsilver.log import *
+from pyclearsilver import httpResponses
+import subprocess
+
+import roslib
+
+#debugfull()
+debugoff()
+
+import gc
+
+try:
+ import warnings
+ warnings.resetwarnings()
+ warnings.filterwarnings("ignore")
+except ImportError:
+ pass
+
+import neo_cgi, neo_cs, neo_util
+
+from pyclearsilver import CSPage
+
+import mimetypes
+mimetypes.init(["/etc/mime.types"])
+
+
+gConfig = None
+def setConfig(config):
+ global gConfig
+ gConfig = config
+
+ if not hasattr(gConfig, "gRequireUsername"): gConfig.gRequireUsername = 0
+ if not hasattr(gConfig, "gDataFilePaths"): gConfig.gDataFilePaths = []
+
+
+def split_path(path):
+ # strip off leading slash, it's no fun!
+ return string.split(path, '/')[1:]
+
+def getPackagePath(pkg):
+ cmd = ["rospack", "find", pkg]
+ pkgpath = subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0].strip()
+ return pkgpath
+
+
+class Page:
+ def __init__(self, context):
+ self.context = context
+
+ def setupvars(self):
+
+ self.path = self.context.environ.get("PATH_INFO", '')
+
+ script_name = self.context.environ.get("SCRIPT_NAME",'')
+
+ ## handle the case where the site is located at '/'
+ if not self.path:
+ self.path = script_name
+ script_name = '/'
+
+
+ def start(self):
+ self.setupvars()
+
+ self._path = self.path
+
+ rpath = self._path
+ if not rpath: rpath = '/'
+
+ if rpath == "/": rpath = gConfig.gDefaultPage
+
+ self.path = split_path(rpath)
+
+ username = None
+
+ if len(self.path) == 0:
+ warn("no such path", self.path)
+ self.error(404)
+ return 404
+
+ ## the url form should be:
+ ## /baseuri/username/module/script.py
+
+ cwd = os.getcwd()
+ debug("CWD", cwd)
+
+ module = gConfig.gDefaultModule
+
+ if hasattr(gConfig, "gDataFilePaths"):
+ if self.path[0] in gConfig.gDataFilePaths:
+ fn = apply(os.path.join, [cwd,] + self.path)
+ return outputFile(self.context, fn)
+
+ if gConfig.gRequireUsername:
+ username = self.path[0]
+ n = 1
+ else:
+ n = 0
+
+ debug("self.path", self.path)
+
+ if len(self.path) > 1:
+ module = self.path[n]
+ n = n + 1
+
+ modpath = None
+ app = None
+ if module == "app":
+ module = self.path[n]
+ app = module
+ n = n + 1
+
+ modpath = getPackagePath(module)
+ #roslib.load_manifest(module)
+
+ fn = apply(os.path.join, [modpath] + self.path[n:])
+ moduleRootPath = modpath
+ handlerRoot = apply(os.path.join, [modpath, "cgibin"])
+ moduleTemplatePath = apply(os.path.join, [modpath, "templates"])
+ else:
+ moduleRootPath = apply(os.path.join, ["mod", module])
+ handlerRoot = apply(os.path.join, ["mod", module, "cgibin"])
+ moduleTemplatePath = apply(os.path.join, [cwd, "mod", module, "templates"])
+
+ fn = apply(os.path.join, [cwd, moduleRootPath,] + self.path[n:])
+
+ systemTemplatePath = apply(os.path.join, [cwd, "mod", "webui", "templates"])
+ systemJLIBPath = apply(os.path.join, [cwd, "mod", "webui", "jslib"])
+
+ debug("fn", fn)
+
+ ## if requesting a file, then just output it to the browser.
+ if os.path.isfile(fn):
+ return outputFile(self.context, fn)
+
+ ## manage the Python module Path
+ sys.path.insert(0, os.path.abspath(cwd))
+ if modpath: sys.path.insert(0, os.path.abspath(modpath))
+ sys.path.insert(0, os.path.abspath(moduleRootPath))
+
+ debug("sys.path", sys.path)
+
+ handlerPath = ''
+
+ ## find the first *real* file in the path
+ ## the rest of the path becomes the pathinfo.
+ m = n
+ for m in range(len(self.path)-1, n-2, -1):
+ handlerPath = apply(os.path.join, [handlerRoot, ] + self.path[n:m+1])
+# warn(m, len(self.path), handlerPath)
+
+ if os.path.isdir(handlerPath):
+ sys.path.insert(0, handlerPath)
+ if os.path.isfile(handlerPath): break
+ if os.path.isdir(handlerPath): break
+
+ if m+1 == len(self.path):
+ pathinfo = ''
+ else:
+ pathinfo = apply(os.path.join, self.path[m+1:])
+
+ if os.path.isdir(handlerPath):
+ modulePath = handlerPath
+ moduleFilename = module + "_index.py"
+ handlerPath = os.path.join(modulePath, moduleFilename)
+ else:
+ modulePath, moduleFilename = os.path.split(handlerPath)
+
+ debug(handlerPath, pathinfo)
+ #warn("PATH", handlerPath, pathinfo, modulePath, moduleFilename)
+ #warn("PATH", self.path)
+
+ if not os.path.isfile(handlerPath):
+ self.error(404, handlerPath + " doesn't exist")
+ return 404
+
+ import imp
+
+ moduleName, ext = os.path.splitext(moduleFilename)
+
+ #module = __import__(moduleName)
+ if app:
+ module = __import__("cgibin.%s" % (moduleName, ), {}, {}, (None,))
+ else:
+ module = __import__("mod.%s.cgibin.%s" % (module, moduleName), {}, {}, (None,))
+
+ os.chdir(modulePath)
+# debug(mod)
+ page = module.run(self.context)
+ page.ncgi.hdf.setValue("CGI.BaseURI", gConfig.gBaseURL)
+
+ if gConfig.gRequireUsername:
+ page.ncgi.hdf.setValue("CGI.Username", username)
+ page.username = username
+
+ if hasattr(page, "checkLoginCookie"):
+ if not page._pageparms.has_key("nologin"):
+ try:
+ page.checkLoginCookie()
+ except CSPage.Redirected:
+ return
+
+ page.ncgi.hdf.setValue("CGI.PathInfo", pathinfo)
+ page.clearPaths()
+ page.setPaths([moduleTemplatePath, systemTemplatePath, systemJLIBPath])
+ ret = page.start()
+
+ try:
+ page.db.close()
+ except AttributeError: pass
+
+ page = None
+
+ return ret
+
+ def error(self, ecode, reason=None):
+ message = httpResponses.gHTTPResponses[ecode]
+
+ template = httpResponses.errorMessage_Default
+ if ecode == 404:
+ template = httpResponses.errorMessage_404
+
+ hdf = neo_util.HDF()
+ hdf.setValue("code", str(ecode))
+ if message: hdf.setValue("message", message)
+ if reason: hdf.setValue("reason", reason)
+
+ for key,val in self.context.environ.items():
+ hdf.setValue("environ." + key, str(val))
+
+ self.context.stdout.write("Content-Type: text/html\r\n")
+ self.context.setStatus(None, ecode)
+ self.context.stdout.write("Status: %s\r\n" % ecode)
+ self.context.stdout.write("\r\n")
+
+ cs = neo_cs.CS(hdf)
+ cs.parseStr(template)
+ page = cs.render()
+
+ self.context.stdout.write(page)
+
+ warn("Error", message, reason)
+
+
+def outputFile(context, fn):
+ fp = open(fn, "rb")
+ data = fp.read()
+ fp.close()
+
+ context.setStatus(None, 200)
+
+ imagetype, encoding = mimetypes.guess_type(fn)
+ debug("imagetype = %s fn = %s" % (imagetype,fn))
+
+ lines = []
+
+ if imagetype:
+ lines.append("Content-Type: %s" % imagetype)
+
+ lines.append("Content-Length: %d" % len(data))
+
+ stat = os.stat(fn)
+ mtime = stat.st_mtime
+ mod_str = time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime(mtime))
+
+ lines.append('Last-Modified: %s GMT' % mod_str)
+
+ expire_time = time.gmtime(time.time() + (360*24*3600))
+ expire_str = time.strftime("%a, %d %b %Y %H:%M:%S", expire_time)
+ lines.append('Expires: %s GMT' % expire_str)
+
+ lines.append("\r\n")
+
+ headers = string.join(lines, "\r\n")
+ context.stdout.write(headers)
+
+ context.stdout.write(data)
+
+ return 200
+
+
+class FakeError:
+ def write(self, s):
+ apache.log_error(s, apache.APLOG_STARTUP)
+
+class ModPythonContext:
+ def __init__ (self, req):
+
+ from mod_python import apache
+
+ self.stdout = apache.CGIStdout(req)
+ self.stdin = apache.CGIStdin(req)
+
+ self.stderr = FakeError()
+ env = apache.build_cgi_env(req)
+
+ self.environ = env
+
+ scriptFilename = self.environ.get("SCRIPT_FILENAME", "")
+ if scriptFilename:
+ path, fn = os.path.split(scriptFilename)
+ os.chdir(path)
+
+ def setStatus(self, request, status):
+ if request:
+ request['status'] = str(status)
+
+
+
+def handler(req):
+ start = time.time()
+
+ from mod_python import apache
+
+ if 1:
+ context = ModPythonContext(req)
+ page = Page(context)
+ page.mod_python_req = req
+
+ gc.enable()
+ ret = page.start()
+ gc.collect()
+
+ ret = apache.OK
+
+ end = time.time()
+ #sys.stderr.write("handler time %s\n" % int((end-start)*1000))
+
+ return ret
+
+
+def main(argv, stdout, environ):
+ context = CSPage.Context()
+ page = Page(context)
+ page.start()
+
+
+if __name__ == "__main__":
+ main(sys.argv, sys.stdout, os.environ)
Property changes on: pkg/trunk/sandbox/web/webui/src/webui/cgistarter.py
___________________________________________________________________
Added: svn:executable
+ *
Added: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/appcon.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/appcon.py (rev 0)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/appcon.py 2009-08-27 05:37:29 UTC (rev 23108)
@@ -0,0 +1,67 @@
+#! /usr/bin/env python
+
+"""
+usage: %(progname)s
+ install [taskid]
+ remove [taskid]
+ list
+"""
+
+
+import os, sys, string, time, getopt
+
+PKG = 'webui' # this package name
+import roslib; roslib.load_manifest(PKG)
+
+from pyclearsilver.log import *
+
+import db_webui
+
+def test():
+ pass
+
+def usage(progname):
+ print __doc__ % vars()
+
+def main(argv, stdout, environ):
+ progname = argv[0]
+ optlist, args = getopt.getopt(argv[1:], "", ["help", "test", "debug"])
+
+ testflag = 0
+ if len(args) == 0:
+ usage(progname)
+ return
+ for (field, val) in optlist:
+ if field == "--help":
+ usage(progname)
+ return
+ elif field == "--debug":
+ debugfull()
+ elif field == "--test":
+ testflag = 1
+
+ if testflag:
+ test()
+ return
+
+ db = db_webui.initSchema()
+
+ cmd = args[0]
+ args = args[1:]
+
+ if cmd == "list":
+ apps = db.apps.listApps()
+ for app in apps:
+ print app.taskid
+ elif cmd == "install":
+ for taskid in args:
+ db.apps.installApp(taskid)
+ elif cmd == "remove":
+ for taskid in args:
+ db.apps.removeApp(taskid)
+
+
+
+
+if __name__ == "__main__":
+ main(sys.argv, sys.stdout, os.environ)
Property changes on: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/appcon.py
___________________________________________________________________
Added: svn:executable
+ *
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py 2009-08-27 05:09:26 UTC (rev 23107)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py 2009-08-27 05:37:29 UTC (rev 23108)
@@ -81,11 +81,21 @@
row.taskid = taskid
row.save()
+ def removeApp(self, taskid):
+ row = self.lookup(taskid=taskid)
+ row.delete()
+
+ def listApps(self):
+ rows = self.fetchAllRows()
+ return rows
+
class Application(hdfhelp.HdfRow):
def fetchApp(self, prefix, hdf):
_app = app.App(str(self.taskid))
doc = _app.load_yaml()
+ hdf.setValue(prefix + "." + "package", _app.package)
+
for key, val in doc.items():
if val is not None:
hdf.setValue(prefix + "." + key, val)
Deleted: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/install_app.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/install_app.py 2009-08-27 05:09:26 UTC (rev 23107)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/install_app.py 2009-08-27 05:37:29 UTC (rev 23108)
@@ -1,53 +0,0 @@
-#! /usr/bin/env python
-
-"""
-usage: %(progname)s [args]
-"""
-
-
-import os, sys, string, time, getopt
-
-PKG = 'webui' # this package name
-import roslib; roslib.load_manifest(PKG)
-
-from pyclearsilver.log import *
-
-import db_webui
-
-def test():
- pass
-
-def usage(progname):
- print __doc__ % vars()
-
-def main(argv, stdout, environ):
- progname = argv[0]
- optlist, args = getopt.getopt(argv[1:], "", ["help", "test", "debug"])
-
- testflag = 0
- if len(args) == 0:
- usage(progname)
- return
- for (field, val) in optlist:
- if field == "--help":
- usage(progname)
- return
- elif field == "--debug":
- debugfull()
- elif field == "--test":
- testflag = 1
-
- if testflag:
- test()
- return
-
- db = db_webui.initSchema()
-
-
- for appfn in args:
- db.apps.installApp(appfn)
-
-
-
-if __name__ == "__main__":
- main(sys.argv, sys.stdout, os.environ)
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_widgets.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_widgets.js 2009-08-27 05:09:26 UTC (rev 23107)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_widgets.js 2009-08-27 05:37:29 UTC (rev 23108)
@@ -28,7 +28,7 @@
init: function() {
this.img = new Image();
- this.img.src = 'templates/images/toolbar/battery_gray.png';
+ this.img.src = '/webui/webui/templates/images/toolbar/battery_gray.png';
this.domobj.innerHTML = '<canvas width=41 height=16></canvas><span style="font-size:11px;position:relative;top:-3"></span>'
var width = this.domobj.getAttribute("width");
@@ -80,7 +80,7 @@
src = 'orange_ball.png';
else
src = 'red_ball.png';
- html += '<img src="templates/images/toolbar/' + src + '"> ';
+ html += '<img src="/webui/webui/templates/images/toolbar/' + src + '"> ';
}
html += '</span>';
this.domobj.innerHTML = html;
@@ -109,7 +109,7 @@
} else {
src = 'battery_power.png';
}
- this.domobj.innerHTML = '<img src="templates/images/toolbar/' + src + '"> ';
+ this.domobj.innerHTML = '<img src="/webui/webui/templates/images/toolbar/' + src + '"> ';
}
});
Modified: pkg/trunk/sandbox/web/we...
[truncated message content] |
|
From: <rob...@us...> - 2009-09-01 17:01:34
|
Revision: 23541
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=23541&view=rev
Author: rob_wheeler
Date: 2009-09-01 17:01:24 +0000 (Tue, 01 Sep 2009)
Log Message:
-----------
Checkpoint the navigation web application
Added Paths:
-----------
pkg/trunk/sandbox/web/navigation_application/
pkg/trunk/sandbox/web/navigation_application/cgibin/
pkg/trunk/sandbox/web/navigation_application/cgibin/__init__.py
pkg/trunk/sandbox/web/navigation_application/cgibin/navigation_application_index.py
pkg/trunk/sandbox/web/navigation_application/images/
pkg/trunk/sandbox/web/navigation_application/images/screenshot.jpg
pkg/trunk/sandbox/web/navigation_application/jslib/
pkg/trunk/sandbox/web/navigation_application/jslib/map_viewer.js
pkg/trunk/sandbox/web/navigation_application/manifest.xml
pkg/trunk/sandbox/web/navigation_application/navigation_application.app
pkg/trunk/sandbox/web/navigation_application/templates/
pkg/trunk/sandbox/web/navigation_application/templates/index.cs
Added: pkg/trunk/sandbox/web/navigation_application/cgibin/navigation_application_index.py
===================================================================
--- pkg/trunk/sandbox/web/navigation_application/cgibin/navigation_application_index.py (rev 0)
+++ pkg/trunk/sandbox/web/navigation_application/cgibin/navigation_application_index.py 2009-09-01 17:01:24 UTC (rev 23541)
@@ -0,0 +1,30 @@
+#! /usr/bin/env python
+
+"""
+usage: %(progname)s [args]
+"""
+
+import os, sys, string, time, getopt, re
+import neo_cgi, neo_util, neo_cs
+from pyclearsilver.log import *
+from pyclearsilver import CSPage, odb
+
+from webui import MBPage
+
+class MyPage(MBPage.MBPage):
+ def setup(self, hdf):
+ pass
+
+ def display(self, hdf):
+ pass
+
+
+def run(context):
+ return MyPage(context, pagename="index", nologin=1)
+
+def main():
+ context = CSPage.Context()
+ run(context).start()
+
+if __name__ == "__main__":
+ main()
Property changes on: pkg/trunk/sandbox/web/navigation_application/cgibin/navigation_application_index.py
___________________________________________________________________
Added: svn:executable
+ *
Added: pkg/trunk/sandbox/web/navigation_application/images/screenshot.jpg
===================================================================
(Binary files differ)
Property changes on: pkg/trunk/sandbox/web/navigation_application/images/screenshot.jpg
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: pkg/trunk/sandbox/web/navigation_application/jslib/map_viewer.js
===================================================================
--- pkg/trunk/sandbox/web/navigation_application/jslib/map_viewer.js (rev 0)
+++ pkg/trunk/sandbox/web/navigation_application/jslib/map_viewer.js 2009-09-01 17:01:24 UTC (rev 23541)
@@ -0,0 +1,230 @@
+var MapTile = Class.create({
+ initialize: function(x, y, width, height, scale) {
+ this.left = x;
+ this.top = y;
+ this.width = width;
+ this.height = height;
+ this.scale = scale;
+
+ this.img = new Element("img");
+ this.img.style.position = "absolute";
+ this.img.style.left = this.left;
+ this.img.style.top = this.top;
+ this.load_image();
+
+ $('map_panner').appendChild(this.img);
+ },
+
+ rescale : function(scale) {
+ this.scale = scale;
+ this.load_image();
+ },
+
+ load_image: function() {
+ var url = "http://cib.willowgarage.com:8080/map";
+ url += '?x=' + this.left;
+ url += '&y=' + this.top;
+ url += '&width=' + this.width;
+ url += '&height=' + this.height;
+ url += '&scale=' + this.scale;
+ this.img.src = url;
+ },
+
+ move: function(dx, dy) {
+ this.left += dx;
+ this.top += dy;
+
+ this.img.style.left = this.left;
+ this.img.style.top = this.top;
+
+ this.load_image();
+ },
+});
+
+
+var MapViewer = Class.create({
+ initialize: function(domobj) {
+ this.viewer = domobj;
+ this.topics = domobj.getAttribute("topic").split(',');
+ },
+
+ init: function() {
+ // Overlay a canvas the same size as this div
+ this.canvas = new Element('canvas', {'id': 'map_canvas', 'width': this.viewer.getWidth(), 'height': this.viewer.getHeight(), 'style': 'z-index:1;position:absolute'});
+ this.viewer.appendChild(this.canvas);
+
+ // Create a div to contain the image tiles
+ this.panner = new Element('div', {'id': 'map_panner', 'style': 'padding:0;position:absolute;top:0px;left:0px;z-index:0'});
+ this.viewer.appendChild(this.panner);
+
+ this.sourceWidth = 2332;
+ this.sourceHeight = 1825;
+ this.sourceResolution = 0.025;
+ this.tileWidth = 256;
+ this.tileHeight = 256;
+ this.scale = 1.0;
+ this.dim = this.viewer.getDimensions();
+ this.tilesWide = Math.floor((this.dim.width + this.tileWidth - 1) / this.tileWidth + 2);
+ this.tilesHigh = Math.floor((this.dim.height + this.tileHeight - 1) / this.tileHeight + 2);
+
+ // Create tiles
+ this.tiles = [];
+ for (var row = 0; row < this.tilesHigh; ++row) {
+ for (var col = 0; col < this.tilesWide; ++col) {
+ this.tiles.push(new MapTile((col-1)*this.tileWidth, (row-1)*this.tileHeight, this.tileWidth, this.tileHeight, this.scale));
+ }
+ }
+
+ // Register event handlers
+ this.viewer.observe('mousedown', this.handleMouseDown.bind(this));
+ this.viewer.observe('dblclick', this.handleDblClick.bind(this));
+ Event.observe(document, 'mouseup', this.handleMouseUp.bind(this));
+ Event.observe(document, 'mousemove', this.handleMouseMove.bind(this));
+ Event.observe(document, 'keypress', this.handleKeyPress.bind(this));
+ this.pressed = false;
+ },
+
+ handleDblClick : function(e) {
+ if (Event.isLeftClick(e)) {
+ var off = this.viewer.cumulativeOffset();
+ this.zoom(-0.25,
+ Event.pointerX(e) - off.left,
+ Event.pointerY(e) - off.top);
+ }
+ },
+
+ handleMouseDown : function(e) {
+ if (Event.isLeftClick(e)) {
+ this.pressed = true;
+ this.mark = [Event.pointerX(e), Event.pointerY(e)];
+ }
+ },
+
+ handleMouseUp : function(e) {
+ if (Event.isLeftClick(e)) {
+ this.pressed = false;
+ }
+ },
+
+ handleMouseMove : function(e) {
+ if (this.pressed) {
+ var old_mark = this.mark;
+ this.mark = [Event.pointerX(e), Event.pointerY(e)];
+ this.panMap(this.mark[0] - old_mark[0],
+ this.mark[1] - old_mark[1]);
+ }
+ },
+
+ handleKeyPress : function(e) {
+ if (e.keyCode == 37) { // Left
+ this.panMap(-10, 0);
+ } else if (e.keyCode == 38) { // Up
+ if (e.ctrlKey)
+ this.zoom(-0.25, 0, 0);
+ else
+ this.panMap(0, -10);
+ } else if (e.keyCode == 39) { // Right
+ this.panMap(10, 0);
+ } else if (e.keyCode == 40) { // Down
+ if (e.ctrlKey)
+ this.zoom(0.25, 0, 0);
+ else
+ this.panMap(0, 10);
+ }
+ },
+
+ zoom : function(factor, center_x, center_y) {
+ this.scale += factor;
+ for (var i = 0; i < this.tiles.length; ++i) {
+ var tile = this.tiles[i];
+ tile.rescale(this.scale);
+ }
+ this.drawRobot();
+ },
+
+ panMap : function(x, y) {
+ var left = parseInt(this.panner.style.left) + x;
+ var top = parseInt(this.panner.style.top) + y;
+ if (left > 0) left = 0;
+ if (top > 0) top = 0;
+ if (left < (this.dim.width - this.sourceWidth/this.scale))
+ left = this.dim.width - this.sourceWidth/this.scale;
+ if (top < (this.dim.height - this.sourceHeight/this.scale))
+ top = this.dim.height - this.sourceHeight/this.scale;
+ this.panner.style.left = left;
+ this.panner.style.top = top;
+
+ for (var i = 0; i < this.tiles.length; ++i) {
+ var tile = this.tiles[i];
+ var tileLeft = left + tile.left;
+ var tileTop = top + tile.top;
+ var dx = 0, dy = 0;
+ if (tileLeft + tile.width < -this.tileWidth)
+ dx += this.tilesWide * this.tileWidth;
+ else if (tileLeft > (this.dim.width + this.tileWidth))
+ dx -= this.tilesWide * this.tileWidth;
+ if (tileTop + parseInt(tile.height) < -this.tileHeight)
+ dy += this.tilesHigh * this.tileHeight;
+ else if (tileTop > (this.dim.height + this.tileHeight))
+ dy -= this.tilesHigh * this.tileHeight;
+ if (dx || dy) tile.move(dx, dy);
+ }
+ this.drawRobot();
+ },
+
+ mapToPixel: function(p) {
+ var x = Math.floor(p.x / this.scale / this.sourceResolution);
+ var y = this.sourceHeight / this.scale - Math.floor(p.y / this.scale / this.sourceResolution);
+ x += parseInt(this.panner.style.left);
+ y += parseInt(this.panner.style.top);
+ return [x, y];
+ },
+
+ drawRobot: function() {
+ var ctx = this.canvas.getContext('2d');
+ ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
+
+ // Draw plan
+ if (this.plan) {
+ ctx.strokeStyle = "rgb(0, 255, 0)";
+ ctx.beginPath();
+ var p = this.mapToPixel(this.plan[0].pose.position);
+ ctx.moveTo(p[0], p[1]);
+ for (var i = 1; i < this.plan.length; ++i) {
+ p = this.mapToPixel(this.plan[i].pose.position);
+ ctx.lineTo(p[0], p[1]);
+ }
+ ctx.stroke();
+ }
+
+ // Draw robot footprint
+ if (this.footprint) {
+ ctx.strokeStyle = "rgb(255, 0, 0)";
+ ctx.beginPath();
+ var p = this.mapToPixel(this.footprint[0]);
+ ctx.moveTo(p[0], p[1]);
+ for (var i = 1; i < this.footprint.length; ++i) {
+ p = this.mapToPixel(this.footprint[i]);
+ ctx.lineTo(p[0], p[1]);
+ }
+ ctx.closePath();
+ ctx.stroke();
+ }
+ },
+
+ receive: function(msg) {
+ var ctx = this.canvas.getContext('2d');
+ ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
+ if (msg.polygon) {
+ this.footprint = msg.polygon.points;
+ } else if (msg.poses) {
+ this.plan = msg.poses;
+ }
+ this.drawRobot();
+ },
+
+});
+
+gRosClasses['MapViewer'] = function(dom) {
+ return new MapViewer(dom);
+}
Added: pkg/trunk/sandbox/web/navigation_application/manifest.xml
===================================================================
--- pkg/trunk/sandbox/web/navigation_application/manifest.xml (rev 0)
+++ pkg/trunk/sandbox/web/navigation_application/manifest.xml 2009-09-01 17:01:24 UTC (rev 23541)
@@ -0,0 +1,14 @@
+<package>
+ <description brief="navigation">
+ Navigation Application
+ </description>
+ <author>Scott Hassan</author>
+ <license>BSD</license>
+ <review status="unreviewed" notes=""/>
+ <url>http://pr.willowgarage.com/wiki/navigation_application</url>
+ <depend package="roslib"/>
+ <depend package="rospy"/>
+ <depend package="webui"/>
+</package>
+
+
Added: pkg/trunk/sandbox/web/navigation_application/navigation_application.app
===================================================================
--- pkg/trunk/sandbox/web/navigation_application/navigation_application.app (rev 0)
+++ pkg/trunk/sandbox/web/navigation_application/navigation_application.app 2009-09-01 17:01:24 UTC (rev 23541)
@@ -0,0 +1,7 @@
+name: Navigation
+package: navigation_application
+launch_file: navigation.launch
+description: A navigation web application
+icon: images/screenshot.jpg
+provides:
+depends:
Added: pkg/trunk/sandbox/web/navigation_application/templates/index.cs
===================================================================
--- pkg/trunk/sandbox/web/navigation_application/templates/index.cs (rev 0)
+++ pkg/trunk/sandbox/web/navigation_application/templates/index.cs 2009-09-01 17:01:24 UTC (rev 23541)
@@ -0,0 +1,28 @@
+<html>
+<head>
+<?cs include:"includes.cs" ?>
+<script type="text/javascript" src="jslib/map_viewer.js"></script>
+</head>
+
+<body onload="ros_handleOnLoad('/ros')">
+<?cs include:"header.cs" ?>
+<h3>Navigation</h3>
+
+<table align=right>
+<td>
+<input class=app_button type=button value="" objtype="LaunchButtonWidget2" topic="/app_update" taskid="<?cs var:CGI.cur.app.taskid ?>">
+<div class=app_status objtype=TextWidget topic="/app_update" key=status selector="taskid" selectorValue="<?cs var:CGI.cur.app.taskid?>"> </div>
+</td>
+</table>
+
+<table width=80% align=center>
+<tr>
+<td>
+<div style="position:absolute;overflow:hidden;width:80%;height:600;border:red 2px solid" objtype=MapViewer topic="/move_base/TrajectoryPlannerROS/robot_footprint,/move_base/NavfnROS/plan"></div><br>
+</td>
+</table>
+
+<div id=ErrorDiv></div>
+
+</body>
+</html>
Property changes on: pkg/trunk/sandbox/web/navigation_application/templates/index.cs
___________________________________________________________________
Added: svn:executable
+ *
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rob...@us...> - 2009-09-02 00:54:13
|
Revision: 23624
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=23624&view=rev
Author: rob_wheeler
Date: 2009-09-02 00:54:03 +0000 (Wed, 02 Sep 2009)
Log Message:
-----------
Facilitate widgets listening on multiple topics by passing the topic name
along with the message to the widget's receive function.
Make the zoom function zoom to a particular point.
Replace the robot footprint with a png of the robot.
Modified Paths:
--------------
pkg/trunk/sandbox/web/navigation_application/jslib/map_viewer.js
pkg/trunk/sandbox/web/navigation_application/templates/index.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_graph.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_pb.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_widgets.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros_toolbar.js
Added Paths:
-----------
pkg/trunk/sandbox/web/navigation_application/images/pr2_small.png
Added: pkg/trunk/sandbox/web/navigation_application/images/pr2_small.png
===================================================================
(Binary files differ)
Property changes on: pkg/trunk/sandbox/web/navigation_application/images/pr2_small.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Modified: pkg/trunk/sandbox/web/navigation_application/jslib/map_viewer.js
===================================================================
--- pkg/trunk/sandbox/web/navigation_application/jslib/map_viewer.js 2009-09-02 00:28:09 UTC (rev 23623)
+++ pkg/trunk/sandbox/web/navigation_application/jslib/map_viewer.js 2009-09-02 00:54:03 UTC (rev 23624)
@@ -45,7 +45,9 @@
var MapViewer = Class.create({
initialize: function(domobj) {
this.viewer = domobj;
- this.topics = domobj.getAttribute("topic").split(',');
+ //this.topics = ['/robot_pose_visualization', '/move_base/NavfnROS/plan'];
+ //this.topics = ['/robot_pose_visualization', '/move_base/TrajectoryPlannerROS/robot_footprint'];
+ this.topics = ['/robot_pose_visualization'];
},
init: function() {
@@ -84,12 +86,15 @@
this.panning = false;
this.settingGoal = false;
this.settingPose = false;
+
+ this.robot_img = new Image();
+ this.robot_img.src = window.location.pathname + '/images/pr2_small.png';
},
handleDblClick : function(e) {
if (Event.isLeftClick(e)) {
var off = this.viewer.cumulativeOffset();
- this.zoom(-0.25,
+ this.zoom(e.ctrlKey ? 0.25 : -0.25,
Event.pointerX(e) - off.left,
Event.pointerY(e) - off.top);
}
@@ -137,31 +142,41 @@
this.panMap(-10, 0);
} else if (e.keyCode == 38) { // Up
if (e.ctrlKey)
- this.zoom(-0.25, 0, 0);
+ this.zoom(-0.25, this.dim.width/2, this.dim.height/2);
else
this.panMap(0, -10);
} else if (e.keyCode == 39) { // Right
this.panMap(10, 0);
} else if (e.keyCode == 40) { // Down
if (e.ctrlKey)
- this.zoom(0.25, 0, 0);
+ this.zoom(0.25, this.dim.width/2, this.dim.height/2);
else
this.panMap(0, 10);
}
},
zoom : function(factor, center_x, center_y) {
+ var center = this.pixelToMap([center_x, center_y]);
this.scale += factor;
+
+ var x = Math.floor(center.x / this.scale / this.sourceResolution);
+ var y = this.sourceHeight / this.scale - Math.floor(center.y / this.scale / this.sourceResolution);
+
+ this.panMap(this.dim.width/2-x, this.dim.height/2-y, false);
for (var i = 0; i < this.tiles.length; ++i) {
var tile = this.tiles[i];
tile.rescale(this.scale);
}
- this.drawRobot();
+ this.updateCanvas();
},
- panMap : function(x, y) {
- var left = parseInt(this.panner.style.left) + x;
- var top = parseInt(this.panner.style.top) + y;
+ panMap : function(x, y, relative) {
+ var left = x;
+ var top = y;
+ if (typeof(relative) != 'undefined' ? relative : true) {
+ left = parseInt(this.panner.style.left) + x;
+ top = parseInt(this.panner.style.top) + y;
+ }
if (left > 0) left = 0;
if (top > 0) top = 0;
if (left < (this.dim.width - this.sourceWidth/this.scale))
@@ -186,7 +201,7 @@
dy -= this.tilesHigh * this.tileHeight;
if (dx || dy) tile.move(dx, dy);
}
- this.drawRobot();
+ this.updateCanvas();
},
pixelToMap: function(p) {
@@ -206,10 +221,32 @@
return [x, y];
},
- drawRobot: function() {
+ updateCanvas: function() {
var ctx = this.canvas.getContext('2d');
ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
+ if (0) {
+ ctx.strokeStyle = "rgb(0, 0, 255)";
+ ctx.beginPath();
+ ctx.moveTo(this.canvas.width/2 - 5, this.canvas.height/2 - 0);
+ ctx.lineTo(this.canvas.width/2 + 5, this.canvas.height/2 - 0);
+ ctx.moveTo(this.canvas.width/2 - 0, this.canvas.height/2 - 5);
+ ctx.lineTo(this.canvas.width/2 - 0, this.canvas.height/2 + 5);
+ ctx.stroke();
+ }
+
+ if (this.robot) {
+ var coords = this.mapToPixel(this.robot);
+ ctx.save();
+ ctx.translate(coords[0], coords[1]);
+ ctx.rotate(this.robot.angle);
+ var sx = 0.65 / (this.robot_img.width * this.sourceResolution * this.scale);
+ var sy = 0.65 / (this.robot_img.height * this.sourceResolution * this.scale);
+ ctx.scale(sx, sy);
+ ctx.drawImage(this.robot_img, -this.robot_img.width / 2, -this.robot_img.height / 2);
+ ctx.restore();
+ }
+
// Draw plan
if (this.plan) {
ctx.strokeStyle = "rgb(0, 255, 0)";
@@ -238,15 +275,40 @@
}
},
- receive: function(msg) {
- var ctx = this.canvas.getContext('2d');
- ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
- if (msg.polygon) {
+ quaternionToEuler: function (q)
+ {
+ result = {'r':0.0, 'p':0.0, 'y':0.0};
+
+ var sqw = q.w * q.w;
+ var sqx = q.x * q.x;
+ var sqy = q.y * q.y;
+ var sqz = q.z * q.z;
+
+ // Roll
+ result.r = Math.atan2(2 * (q.y*q.z + q.w*q.x), sqw - sqx - sqy + sqz);
+
+ // Pitch
+ result.p = Math.asin(-2 * (q.x*q.z - q.w * q.y));
+
+ // Yaw
+ result.y = Math.atan2(2 * (q.x*q.y + q.w*q.z), sqw + sqx - sqy - sqz);
+
+ return result;
+ },
+
+ receive: function(topic, msg) {
+ if (topic == '/robot_pose_visualization') {
+ var angle = -this.quaternionToEuler(msg.pose.orientation).y;
+ this.robot = {'x': msg.pose.position.x,
+ 'y': msg.pose.position.y,
+ 'angle': angle};
+ } else if (topic == '/move_base/NavfnROS/plan') {
+ ros_debug('new plan: ' + msg.poses.length + ' poses');
+ this.plan = msg.poses;
+ } else if (topic == '/move_base/TrajectoryPlannerROS/robot_footprint') {
this.footprint = msg.polygon.points;
- } else if (msg.poses) {
- this.plan = msg.poses;
}
- this.drawRobot();
+ this.updateCanvas();
},
});
Modified: pkg/trunk/sandbox/web/navigation_application/templates/index.cs
===================================================================
--- pkg/trunk/sandbox/web/navigation_application/templates/index.cs 2009-09-02 00:28:09 UTC (rev 23623)
+++ pkg/trunk/sandbox/web/navigation_application/templates/index.cs 2009-09-02 00:54:03 UTC (rev 23624)
@@ -18,7 +18,7 @@
<table width=80% align=center>
<tr>
<td>
-<div style="position:absolute;overflow:hidden;width:80%;height:600;border:red 2px solid" objtype=MapViewer topic="/move_base/TrajectoryPlannerROS/robot_footprint,/move_base/NavfnROS/plan"></div><br>
+<div style="position:absolute;overflow:hidden;width:80%;height:600;border:2px solid" objtype=MapViewer></div><br>
</td>
</table>
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_graph.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_graph.js 2009-09-02 00:28:09 UTC (rev 23623)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_graph.js 2009-09-02 00:54:03 UTC (rev 23624)
@@ -36,7 +36,7 @@
this.chart.draw(this.data, this.options);
},
- receive: function(msg) {
+ receive: function(topic, msg) {
var pbmsg = msg.status[0]
if(pbmsg.name == "Power board 0") {
if(this.data.getNumberOfRows() > 60) {
@@ -93,7 +93,7 @@
this.chart.draw(this.data, this.options);
},
- receive: function(msg) {
+ receive: function(topic, msg) {
var pbmsg = msg.status[0]
if(pbmsg.name == "Power board 0") {
if(this.data.getNumberOfRows() > 60) {
@@ -153,7 +153,7 @@
this.chart.draw(this.data, this.options);
},
- receive: function(msg) {
+ receive: function(topic, msg) {
if(this.data.getNumberOfRows() > 60) {
this.data.removeRow(0);
}
@@ -181,7 +181,7 @@
init: function() {
},
- receive: function(msg) {
+ receive: function(topic, msg) {
var pbmsg = msg.status[0]
if(pbmsg.name == "Power board 0") {
var cb0 = pbmsg.strings[1].value + " @ " + pbmsg.values[4].value.toFixed(2) + "V";
@@ -235,7 +235,7 @@
this.chart.draw(this.data, this.options);
},
- receive: function(msg) {
+ receive: function(topic, msg) {
if(msg[this.key] != null) {
var percent = 100. * parseFloat(msg[this.key]) / parseFloat(msg[this.key2]);
this.data.setValue(0, 1, percent|0);
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_pb.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_pb.js 2009-09-02 00:28:09 UTC (rev 23623)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_pb.js 2009-09-02 00:54:03 UTC (rev 23624)
@@ -9,7 +9,7 @@
init: function() {
},
- receive: function(msg) {
+ receive: function(topic, msg) {
var pbmsg = msg.status[0]
if(pbmsg.name == "Power board 0") {
var state = null;
@@ -52,7 +52,7 @@
init: function() {
},
- receive: function(msg) {
+ receive: function(topic, msg) {
var pbmsg = msg.status[0]
if(pbmsg.name == "Power board 0") {
var estop_button_status = null;
@@ -112,7 +112,7 @@
init: function() {
},
- receive: function(msg) {
+ receive: function(topic, msg) {
var pbmsg = msg.status[0]
if(pbmsg.name == "Power board 0") {
var estop_button_status = null;
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_widgets.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_widgets.js 2009-09-02 00:28:09 UTC (rev 23623)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_widgets.js 2009-09-02 00:54:03 UTC (rev 23624)
@@ -43,7 +43,7 @@
this.draw();
},
- receive: function(msg) {
+ receive: function(topic, msg) {
if(msg['energy_remaining'] != null) {
this.percent = Math.round(100. * parseFloat(msg['energy_remaining']) / parseFloat(msg['energy_capacity']));
if (this.percent > 100) this.percent = 100;
@@ -69,7 +69,7 @@
this.domobj.innerHTML = html;
},
- receive: function(msg) {
+ receive: function(topic, msg) {
var html = '<span style="font-size:11px;position:relative;top:-3">Circuits:</span><span>';
var states = msg['circuit_state'];
for (var i = 0; i < 3; ++i) {
@@ -100,7 +100,7 @@
init: function() {
},
- receive: function(msg) {
+ receive: function(topic, msg) {
var voltage = msg['input_voltage'];
var src;
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js 2009-09-02 00:28:09 UTC (rev 23623)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js 2009-09-02 00:54:03 UTC (rev 23624)
@@ -87,7 +87,7 @@
if(listeners) {
for(var j=0; j<listeners.length; j++) {
try {
- listeners[j].receive(msgEnv.msg);
+ listeners[j].receive(msgEnv.topic, msgEnv.msg);
} catch (e) {
ros_debug("Error with receiver.");
}
@@ -215,7 +215,7 @@
}
},
- receive: function(msg) {
+ receive: function(topic, msg) {
if(this.selector && this.selectorValue) {
if(msg[this.selector] != this.selectorValue) return;
}
@@ -260,7 +260,7 @@
init: function() {
},
- receive: function(msg) {
+ receive: function(topic, msg) {
if(!this.selector || !this.selectorValue) return;
if(this.selector && this.selectorValue) {
@@ -290,7 +290,7 @@
init: function() {
},
- receive: function(msg) {
+ receive: function(topic, msg) {
if(msg[this.key] != null) {
var percent = parseFloat(msg[this.key]) / parseFloat(msg[this.key2]);
this.domobj.innerHTML = (100. * percent).toFixed(2) + "%";
@@ -330,7 +330,7 @@
this.textdiv.appendChild(d);
},
- receive: function(msg) {
+ receive: function(topic, msg) {
this.new_message(msg);
if(this.textdiv.childNodes.length > this.maxlines) {
this.textdiv.removeChild(this.textdiv.childNodes[0]);
@@ -380,7 +380,7 @@
this.domobj.innerHTML = "";
},
- receive: function(msg) {
+ receive: function(topic, msg) {
if(msg[this.key] != null) {
var lst = msg[this.key];
var s = "";
@@ -413,7 +413,7 @@
this.domobj.innerHTML = "";
},
- receive: function(msg) {
+ receive: function(topic, msg) {
var s = "<ul>";
for(var key in msg) {
s = s + "<li>" + key + ": " + msg[key];
@@ -497,7 +497,7 @@
//c.appendChild(tn);
},
- receive: function(msg) {
+ receive: function(topic, msg) {
this.new_message(msg);
if(this.tbl.rows.length > this.maxlines) {
this.tbl.deleteRow(0);
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros_toolbar.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros_toolbar.js 2009-09-02 00:28:09 UTC (rev 23623)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros_toolbar.js 2009-09-02 00:54:03 UTC (rev 23624)
@@ -23,7 +23,7 @@
//this.pump.service_call("status_update", []);
},
- receive: function(msg) {
+ receive: function(topic, msg) {
if(msg.taskid != this.taskid) return;
var prev_state = this.state;
@@ -81,7 +81,7 @@
this.set_state();
},
- receive: function(msg) {
+ receive: function(topic, msg) {
if(msg.taskid != this.taskid) return;
var prev_state = this.state;
@@ -138,7 +138,7 @@
this.domobj.innerHTML = "";
},
- receive: function(msg) {
+ receive: function(topic, msg) {
var s = "";
for(var i=0; i<msg.active.length; i++) {
s = s + "|" + "<a href='/webui/app/" + msg.active[i].taskid + "'>" + msg.active[i].name + "</a>";
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wgh...@us...> - 2009-09-02 07:14:27
|
Revision: 23679
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=23679&view=rev
Author: wghassan
Date: 2009-09-02 07:14:20 +0000 (Wed, 02 Sep 2009)
Log Message:
-----------
added compression and keep-alive to the rosweb
Modified Paths:
--------------
pkg/trunk/sandbox/web/rosweb2/src/rosweb.py
pkg/trunk/sandbox/web/sample_application/templates/index.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_widgets.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/includes.cs
Added Paths:
-----------
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/xss.js
Modified: pkg/trunk/sandbox/web/rosweb2/src/rosweb.py
===================================================================
--- pkg/trunk/sandbox/web/rosweb2/src/rosweb.py 2009-09-02 06:53:44 UTC (rev 23678)
+++ pkg/trunk/sandbox/web/rosweb2/src/rosweb.py 2009-09-02 07:14:20 UTC (rev 23679)
@@ -43,6 +43,7 @@
import sys
import threading
import time
+import gzip
import traceback
import BaseHTTPServer
import logging
@@ -369,9 +370,26 @@
self.send_header('Content-Type', 'text/javascript')
else:
self.send_header('Content-Type', 'application/json')
+
+ if len(buf) > 500:
+ acceptEncoding = self.headers.get('Accept-Encoding', '')
+ if acceptEncoding.find('gzip') != -1:
+ zbuf = cStringIO.StringIO()
+ zfile = gzip.GzipFile(None, "wb", 9, zbuf)
+ zfile.write(buf)
+ zfile.close()
+
+ nbuf = len(buf)
+ buf = zbuf.getvalue()
+ self.send_header('Content-encoding', 'gzip')
+ print "%d/%d" % (len(buf), nbuf)
+
self.send_header('Content-Length', str(len(buf)))
+
+ self.send_header('Connection', 'keep-alive')
self.end_headers()
+
self.wfile.write(buf)
except socket.error, (ecode, reason):
if ecode == 32:
Modified: pkg/trunk/sandbox/web/sample_application/templates/index.cs
===================================================================
--- pkg/trunk/sandbox/web/sample_application/templates/index.cs 2009-09-02 06:53:44 UTC (rev 23678)
+++ pkg/trunk/sandbox/web/sample_application/templates/index.cs 2009-09-02 07:14:20 UTC (rev 23679)
@@ -17,7 +17,7 @@
<table width=80% align=center>
<tr>
<td>
-<div style="align: center; border: 1px solid black; font-size: 10pt; font-family: courier; height: 40em; width: 60em;" objtype=ScrollingTextWidget topic="/chatter"></div><br>
+<div style="align: center; border: 1px solid black; font-size: 10pt; font-family: courier; height: 40em; width: 60em;" objtype=TerminalTextWidget topic="/chatter" key="data"></div><br>
</td>
</table>
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_widgets.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_widgets.js 2009-09-02 06:53:44 UTC (rev 23678)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/pr2_widgets.js 2009-09-02 07:14:20 UTC (rev 23679)
@@ -40,7 +40,7 @@
else height = parseInt(height);
this.percent = 0;
- this.draw();
+ //this.draw();
},
receive: function(topic, msg) {
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js 2009-09-02 06:53:44 UTC (rev 23678)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js 2009-09-02 07:14:20 UTC (rev 23679)
@@ -24,8 +24,9 @@
var oScript = document.getElementById(id);
var head = document.getElementsByTagName("head").item(0);
if (oScript) {
- // Destory object
+ // Destroy object
head.removeChild(oScript);
+ delete oScript;
}
// Create object
oScript = document.createElement("script");
@@ -45,6 +46,8 @@
this.topicListeners = new Hash();
this.widgets = [];
this.http_request = [];
+
+ this.totalReceivedBytes = 0;
},
registerWidget: function(widget) {
@@ -73,7 +76,7 @@
} catch (e) {
ros_debug("Error with evalMessages.");
}
- setTimeout("gPump.pump();", 500);
+ setTimeout("gPump.pump();", 200);
},
evalMessages: function(json_result) {
Added: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/xss.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/xss.js (rev 0)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/xss.js 2009-09-02 07:14:20 UTC (rev 23679)
@@ -0,0 +1,165 @@
+scriptTransport = Class.create();
+//modeled after XmlHttpRequest http://en.wikipedia.org/wiki/XMLHttpRequest
+//functions open, send (setRequestHeader) - variable readyState, status
+//
+// * 0 = uninitialized - open() has not yet been called.
+// * 1 = open - send() has not yet been called.
+// * 2 = sent - send() has been called, headers and status are available.
+// * 3 = receiving - Downloading, responseText holds partial data.
+// * 4 = loaded - Finished.
+
+//TODO:
+//Removal of <script> nodes?
+
+//
+//------------------------------ initialize, open and send ------------------------------------------------------
+//
+
+scriptTransport.prototype.initialize = function() {
+ this.readyState = 0;
+}
+
+scriptTransport.prototype.open = function(method, url, asynchronous) {
+ if (method != 'GET')
+ alert('Method should be set to GET when using cross site ajax');
+ this.readyState = 1;
+ this.onreadystatechange();
+ this.url = url;
+ this.userAgent = navigator.userAgent.toLowerCase();
+ this.setBrowser();
+ this.prepareGetScriptXS();
+}
+
+scriptTransport.prototype.send = function(body) {
+ this.readyState = 2;
+ this.onreadystatechange();
+ this.getScriptXS(this.url);
+}
+
+//
+//------------------------------ actually do the request: setBrowser, prepareGetScriptXS, callback, getScriptXS ----------
+//
+
+scriptTransport.prototype.setBrowser = function(body) {
+ scriptTransport.prototype.browser = {
+ version: (this.userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/) || [])[1],
+ safari: /webkit/.test(this.userAgent),
+ opera: /opera/.test(this.userAgent),
+ msie: /msie/.test(this.userAgent) && !/opera/.test(this.userAgent),
+ mozilla: /mozilla/.test(this.userAgent) && !/(compatible|webkit)/.test(this.userAgent),
+ konqueror: this.userAgent.match(/konqueror/i)
+ };
+}
+
+scriptTransport.prototype.prepareGetScriptXS = function() {
+ if (this.browser.safari || this.browser.konqueror) {
+ _xsajax$node = [];
+ _xsajax$nodes = 0;
+ }
+}
+
+scriptTransport.prototype.callback = function() {
+ this.status = (_xsajax$transport_status) ? _xsajax$transport_status : 200;
+ this.readyState = 4;
+ this.onreadystatechange();
+}
+
+scriptTransport.prototype.getScriptXS = function() {
+
+ /* determine arguments */
+ var arg = {
+ 'url': null
+ };
+ arg.url = arguments[0];
+
+ /* generate <script> node */
+ this.node = document.createElement('SCRIPT');
+ this.node.type = 'text/javascript';
+ this.node.src = arg.url;
+
+ /* optionally apply event handler to <script> node for
+ garbage collecting <script> node after loading and/or
+ calling a custom callback function */
+ var node_helper = null;
+
+ if (this.browser.msie) {
+
+ function mybind(obj) {
+ temp = function() {
+ if (this.readyState == "complete" || this.readyState == "loaded") {
+ return obj.callback.call(obj);
+ }
+ };
+ return temp;
+ }
+ /* MSIE doesn't support the "onload" event on
+ <script> nodes, but it at least supports an
+ "onreadystatechange" event instead. But notice:
+ according to the MSDN documentation we would have
+ to look for the state "complete", but in practice
+ for <script> the state transitions from "loading"
+ to "loaded". So, we check for both here... */
+ this.node.onreadystatechange = mybind(this);
+
+ } else if (this.browser.safari || this.browser.konqueror) {
+ /* Safari/WebKit and Konqueror/KHTML do not emit
+ _any_ events at all, but we can exploit the fact
+ that dynamically generated <script> DOM nodes
+ are executed in sequence (although the scripts
+ theirself are still loaded in parallel) */
+ _xsajax$nodes++;
+
+ var helper = 'var ctx = _xsajax$node[' + _xsajax$nodes + '];' + 'ctx.callback.call(ctx.node);' + 'setTimeout(function () {' + ' ctx.node_helper.parentNode.removeChild(ctx.node_helper);' + '}, 100);';
+ node_helper = document.createElement('SCRIPT');
+ node_helper.type = 'text/javascript';
+ node_helper.appendChild(document.createTextNode(helper));
+ _xsajax$node[_xsajax$nodes] = {
+ callback: this.callback.bind(this),
+ node: this.node,
+ node_helper: node_helper
+ };
+ } else {
+ /* Firefox, Opera and other reasonable browsers can
+ use the regular "onload" event... */
+ this.node.onload = this.callback.bind(this);
+ }
+
+ /* inject <script> node into <head> of document */
+ this.readyState = 3;
+ this.onreadystatechange();
+ var head = document.getElementsByTagName('HEAD')[0];
+ head.appendChild(this.node);
+
+ /* optionally inject helper <script> node into <head>
+ (Notice: we have to use a strange indirection via
+ setTimeout() to insert this second <script> node here or
+ at least Konqueror (and perhaps also Safari) for unknown
+ reasons will not execute the first <script> node at all) */
+ if (node_helper !== null) {
+ setTimeout(function() {
+ var head = document.getElementsByTagName('HEAD')[0];
+ head.appendChild(node_helper);
+ }, 100);
+ }
+
+}
+
+//
+//------------------------------ Don't complain when these are called: setRequestHeader and onreadystatechange ----------
+//
+
+scriptTransport.prototype.setRequestHeader = function() {
+}
+scriptTransport.prototype.onreadystatechange = function() {
+}
+
+//
+//------------------------------- Extend prototype a bit -----------------------
+//
+Ajax.Request.prototype = Object.extend(Ajax.Request.prototype,{
+ initialize: function(url, options) {
+ this.setOptions(options);
+ this.transport = (!this.options.crossSite) ? Ajax.getTransport() : new scriptTransport;
+ this.request(url);
+ }
+});
\ No newline at end of file
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/includes.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/includes.cs 2009-09-02 06:53:44 UTC (rev 23678)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/includes.cs 2009-09-02 07:14:20 UTC (rev 23679)
@@ -3,6 +3,7 @@
<title>RosWeb: <?cs var:CGI.ServerName?></title>
<script type="text/javascript" src="<?cs var:CGI.ScriptName?>/webui/jslib/prototype.js"></script>
+<script type="text/javascript" src="<?cs var:CGI.ScriptName?>/webui/jslib/xss.js"></script>
<script type="text/javascript" src="<?cs var:CGI.ScriptName?>/webui/jslib/ros.js"></script>
<script type="text/javascript" src="<?cs var:CGI.ScriptName?>/webui/jslib/ros_toolbar.js"></script>
<script type="text/javascript" src="<?cs var:CGI.ScriptName?>/webui/jslib/pr2_graph.js"></script>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wgh...@us...> - 2009-09-02 08:48:41
|
Revision: 23684
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=23684&view=rev
Author: wghassan
Date: 2009-09-02 08:48:31 +0000 (Wed, 02 Sep 2009)
Log Message:
-----------
switch to using xss.js for script tag ajax
Modified Paths:
--------------
pkg/trunk/sandbox/web/rosweb2/src/rosweb.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/nodes.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/status.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/topic.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/topics.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/xss.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/nodes.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/status.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topic.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topics.cs
Added Paths:
-----------
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/rosfooter.cs
Modified: pkg/trunk/sandbox/web/rosweb2/src/rosweb.py
===================================================================
--- pkg/trunk/sandbox/web/rosweb2/src/rosweb.py 2009-09-02 08:35:18 UTC (rev 23683)
+++ pkg/trunk/sandbox/web/rosweb2/src/rosweb.py 2009-09-02 08:48:31 UTC (rev 23684)
@@ -366,7 +366,8 @@
try:
self.send_response(retcode)
if callback:
- buf = callback + "(" + buf + ");"
+ #buf = callback + "(" + buf + "); var _xsajax$transport_status=200;"
+ buf = callback + "=" + buf + ";\nvar _xsajax$transport_status=200;"
self.send_header('Content-Type', 'text/javascript')
else:
self.send_header('Content-Type', 'application/json')
@@ -386,7 +387,8 @@
self.send_header('Content-Length', str(len(buf)))
- self.send_header('Connection', 'keep-alive')
+ if self.headers.get("Connection", '').lower() == "keep-alive":
+ self.send_header('Connection', 'keep-alive')
self.end_headers()
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/nodes.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/nodes.py 2009-09-02 08:35:18 UTC (rev 23683)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/nodes.py 2009-09-02 08:48:31 UTC (rev 23684)
@@ -25,7 +25,7 @@
pass
def display(self, hdf):
- return
+ db_webui.grabTopics(hdf, ["/topics"])
def run(context):
return MyPage(context, pagename="nodes", nologin=1)
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/status.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/status.py 2009-09-02 08:35:18 UTC (rev 23683)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/status.py 2009-09-02 08:48:31 UTC (rev 23684)
@@ -24,10 +24,10 @@
class MyPage(MBPage.MBPage):
def setup(self, hdf):
- self.db = db_webui.initSchema()
+ pass
def display(self, hdf):
- pass
+ db_webui.grabTopics(hdf, ["/rosout", "/users"])
def run(context):
return MyPage(context, pagename="status", nologin=1)
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/topic.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/topic.py 2009-09-02 08:35:18 UTC (rev 23683)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/topic.py 2009-09-02 08:48:31 UTC (rev 23684)
@@ -30,6 +30,8 @@
topic = hdf.getValue("Query.topic", "")
hdf.setValue("CGI.cur.topic", topic)
+ db_webui.grabTopics(hdf, ["/topics", topic, "/battery_state", "/power_board_state", "/app_status"])
+
def run(context):
return MyPage(context, pagename="topic", nologin=1)
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/topics.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/topics.py 2009-09-02 08:35:18 UTC (rev 23683)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/topics.py 2009-09-02 08:48:31 UTC (rev 23684)
@@ -22,10 +22,10 @@
class MyPage(MBPage.MBPage):
def setup(self, hdf):
- self.db = db_webui.initSchema()
-
+ pass
+
def display(self, hdf):
- return
+ db_webui.grabTopics(hdf, ["/topics"])
def run(context):
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py 2009-09-02 08:35:18 UTC (rev 23683)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/db_webui.py 2009-09-02 08:48:31 UTC (rev 23684)
@@ -21,6 +21,21 @@
from launchman import app
+import urllib
+
+def grabTopics(hdf, topics):
+ topics = topics + ["/battery_state", "/power_board_state", "/app_status"]
+ topicList = []
+ for topic in topics: topicList.append("topic=%s" % topic)
+ topics = string.join(topicList, "&")
+
+ url = "http://localhost:8080/ros/receive?since=0&" + topics
+ fp = urllib.urlopen(url)
+ body = fp.read()
+ fp.close()
+
+ hdf.setValue("CGI.cur.messages", body)
+
def path2taskid(path):
p = []
package = None
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js 2009-09-02 08:35:18 UTC (rev 23683)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js 2009-09-02 08:48:31 UTC (rev 23684)
@@ -71,17 +71,16 @@
receive: function(json_result) {
try {
- this.lastTime = json_result.since;
this.evalMessages(json_result);
} catch (e) {
ros_debug("Error with evalMessages.");
}
- setTimeout("gPump.pump();", 200);
+ setTimeout("gPump.pump();", 100);
},
evalMessages: function(json_result) {
// ros_debug("evalMessages()");
-
+ this.lastTime = json_result.since;
for(var i=0; i<json_result.msgs.length; i++) {
var msgEnv = json_result.msgs[i];
// ros_debug(msgEnv.topic);
@@ -132,7 +131,7 @@
});
},
- service_call: function(service_name, parameterList) {
+ service_call_xss: function(service_name, parameterList) {
var parameters = {args: parameterList};
var uri = this.urlprefix + "/service/" + service_name;
@@ -140,17 +139,53 @@
uri = uri + "?callback=gPump.receive_service&json=" + Object.toJSON(parameterList);
getDataFromServer("_ros_service_pump", uri);
},
+
+
+ service_call: function(service_name, parameterList) {
+ var parameters = {args: parameterList};
+
+ var uri = this.urlprefix + "/service/" + service_name;
+ uri = uri + "?callback=gPump.receive_service&json=" + Object.toJSON(parameterList);
+ var parameters = {json: Object.toJSON(parameterList)};
+ new Ajax.Request(uri, {parameters: parameters, crossSite: true, method: 'get'});
+ },
+
receive_server: function(msg) {
alert('receive_server');
},
- pump: function() {
+ pump_xs: function() {
var uri = this.urlprefix + "/receive?callback=gPump.receive&since=" + this.lastTime;
this.topicListeners.each(function(pair) {uri = uri + "&topic=" + pair.key; });
getDataFromServer("_ros_pump", uri);
},
+ pump: function() {
+ var uri = this.urlprefix + "/receive?callback=gMessage&since=" + this.lastTime;
+ this.topicListeners.each(function(pair) {
+ uri = uri + "&topic=" + pair.key;
+ });
+
+ var obj = this;
+ new Ajax.Request(uri, {
+ method: 'get',
+ crossSite: true,
+ onSuccess: function(transport) {
+ try {
+ var json = gMessage;
+ obj.evalMessages(json);
+ obj.pump();
+ } catch(e) {
+ obj.pump();
+ }
+ },
+ onFailure: function(transport) {
+ obj.pump();
+ }
+ });
+ },
+
pump_old: function() {
var uri = this.urlprefix + "/receive?since=" + this.lastTime;
this.topicListeners.each(function(pair) {
@@ -164,9 +199,8 @@
onSuccess: function(transport) {
try {
var json = transport.responseText.evalJSON();
- obj.lastTime = json.since;
+ obj.evalMessages(json);
obj.pump();
- obj.evalMessages(json);
} catch(e) {
obj.pump();
}
@@ -185,7 +219,9 @@
gPump = new MessagePump("http://" + window.location.hostname + ":8080" + prefix);
gPump.setupWidgets();
- //setTimeout("gPump.pump();", 10);
+ if(window.gMessage) {
+ gPump.evalMessages(window.gMessage);
+ }
gPump.pump();
}
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/xss.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/xss.js 2009-09-02 08:35:18 UTC (rev 23683)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/xss.js 2009-09-02 08:48:31 UTC (rev 23684)
@@ -1,4 +1,10 @@
scriptTransport = Class.create();
+//
+//Written by Thierry Schellenbach
+//http://www.mellowmorning.com/2007/10/25/introducing-a-cross-site-ajax-plugin-for-prototype/
+//Version 0.8.0 for Prototype 1.5.0
+//Developed for www.commenthub.com
+//
//modeled after XmlHttpRequest http://en.wikipedia.org/wiki/XMLHttpRequest
//functions open, send (setRequestHeader) - variable readyState, status
//
@@ -7,6 +13,14 @@
// * 2 = sent - send() has been called, headers and status are available.
// * 3 = receiving - Downloading, responseText holds partial data.
// * 4 = loaded - Finished.
+//
+// for which prototype does this:
+// ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']
+// unfortunately the onreadystatechange only works for the last 3, because
+// prototype 1.5.0 assigns it too late, for our usage and prevents status 1
+// Prototype uses a timer, which in tests lead onSuccess to occur before onLoading
+// We use respondToReadyState to make a direct instruction and bypass the filter
+//
//TODO:
//Removal of <script> nodes?
@@ -23,11 +37,12 @@
if (method != 'GET')
alert('Method should be set to GET when using cross site ajax');
this.readyState = 1;
+ /* little hack to get around the late assignment of onreadystatechange */
+ this.respondToReadyState(1);
this.onreadystatechange();
this.url = url;
this.userAgent = navigator.userAgent.toLowerCase();
this.setBrowser();
- this.prepareGetScriptXS();
}
scriptTransport.prototype.send = function(body) {
@@ -51,25 +66,24 @@
};
}
-scriptTransport.prototype.prepareGetScriptXS = function() {
- if (this.browser.safari || this.browser.konqueror) {
- _xsajax$node = [];
- _xsajax$nodes = 0;
+scriptTransport.prototype.callback = function() {
+ try{
+ this.status = _xsajax$transport_status;
+ } catch(e) {
+ return;
+ //to prevent people from writing code, which is not cross browser compatible
}
-}
-
-scriptTransport.prototype.callback = function() {
- this.status = (_xsajax$transport_status) ? _xsajax$transport_status : 200;
this.readyState = 4;
this.onreadystatechange();
+ _xsajax$transport_status = null;
}
scriptTransport.prototype.getScriptXS = function() {
/* determine arguments */
var arg = {
- 'url': null
- };
+ 'url': null
+ }
arg.url = arguments[0];
/* generate <script> node */
@@ -77,13 +91,10 @@
this.node.type = 'text/javascript';
this.node.src = arg.url;
- /* optionally apply event handler to <script> node for
- garbage collecting <script> node after loading and/or
- calling a custom callback function */
- var node_helper = null;
+ /* FF and Opera properly support onload. MSIE has its own implementation. Safari and Konqueror need some polling */
if (this.browser.msie) {
-
+
function mybind(obj) {
temp = function() {
if (this.readyState == "complete" || this.readyState == "loaded") {
@@ -101,24 +112,23 @@
to "loaded". So, we check for both here... */
this.node.onreadystatechange = mybind(this);
- } else if (this.browser.safari || this.browser.konqueror) {
+ } else if (this.browser.safari || this.browser.konqueror) {
+ this.timepassed = 0;
/* Safari/WebKit and Konqueror/KHTML do not emit
- _any_ events at all, but we can exploit the fact
- that dynamically generated <script> DOM nodes
- are executed in sequence (although the scripts
- theirself are still loaded in parallel) */
- _xsajax$nodes++;
-
- var helper = 'var ctx = _xsajax$node[' + _xsajax$nodes + '];' + 'ctx.callback.call(ctx.node);' + 'setTimeout(function () {' + ' ctx.node_helper.parentNode.removeChild(ctx.node_helper);' + '}, 100);';
- node_helper = document.createElement('SCRIPT');
- node_helper.type = 'text/javascript';
- node_helper.appendChild(document.createTextNode(helper));
- _xsajax$node[_xsajax$nodes] = {
- callback: this.callback.bind(this),
- node: this.node,
- node_helper: node_helper
- };
+ _any_ events at all, so we need to use some primitive polling */
+ this.checkTimer = setInterval(function()
+ {
+ this.timepassed = this.timepassed+100;
+ if(typeof(eval(_xsajax$transport_status)) != 'undefined' && eval(_xsajax$transport_status) != null)
+ {
+ this.callback();
+ clearInterval(this.checkTimer);
+ }
+ if(this.timepassed > 20000)
+ clearInterval(this.checkTimer);
+ }.bind(this),100);
} else {
+
/* Firefox, Opera and other reasonable browsers can
use the regular "onload" event... */
this.node.onload = this.callback.bind(this);
@@ -130,18 +140,6 @@
var head = document.getElementsByTagName('HEAD')[0];
head.appendChild(this.node);
- /* optionally inject helper <script> node into <head>
- (Notice: we have to use a strange indirection via
- setTimeout() to insert this second <script> node here or
- at least Konqueror (and perhaps also Safari) for unknown
- reasons will not execute the first <script> node at all) */
- if (node_helper !== null) {
- setTimeout(function() {
- var head = document.getElementsByTagName('HEAD')[0];
- head.appendChild(node_helper);
- }, 100);
- }
-
}
//
@@ -152,14 +150,36 @@
}
scriptTransport.prototype.onreadystatechange = function() {
}
+scriptTransport.prototype.respondToReadyState = function() {
+}
//
//------------------------------- Extend prototype a bit -----------------------
//
Ajax.Request.prototype = Object.extend(Ajax.Request.prototype,{
- initialize: function(url, options) {
- this.setOptions(options);
- this.transport = (!this.options.crossSite) ? Ajax.getTransport() : new scriptTransport;
- this.request(url);
- }
-});
\ No newline at end of file
+ initialize: function(url, options) {
+ this.options = {
+ method: 'post',
+ asynchronous: true,
+ contentType: 'application/x-www-form-urlencoded',
+ encoding: 'UTF-8',
+ parameters: '',
+ evalJSON: true,
+ evalJS: true
+ };
+ Object.extend(this.options, options || { });
+
+ this.options.method = this.options.method.toLowerCase();
+
+ if (Object.isString(this.options.parameters))
+ this.options.parameters = this.options.parameters.toQueryParams();
+ else if (Object.isHash(this.options.parameters))
+ this.options.parameters = this.options.parameters.toObject();
+
+ this.transport = (!this.options.crossSite) ? Ajax.getTransport() : new scriptTransport;
+ this.options.asynchronous = (!this.options.crossSite) ? this.options.asynchronous : false;
+ //turns of the timed onLoad executer
+ this.transport.respondToReadyState = this.respondToReadyState.bind(this);
+ this.request(url);
+ }
+ });
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/nodes.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/nodes.cs 2009-09-02 08:35:18 UTC (rev 23683)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/nodes.cs 2009-09-02 08:48:31 UTC (rev 23684)
@@ -14,5 +14,6 @@
<br>
+<?cs include:"rosfooter.cs"?>
</body>
</html>
Added: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/rosfooter.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/rosfooter.cs (rev 0)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/rosfooter.cs 2009-09-02 08:48:31 UTC (rev 23684)
@@ -0,0 +1,4 @@
+<script type="text/javascript">
+gMessage = <?cs var:CGI.cur.messages ?>;
+</script>
+
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/status.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/status.cs 2009-09-02 08:35:18 UTC (rev 23683)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/status.cs 2009-09-02 08:48:31 UTC (rev 23684)
@@ -31,5 +31,6 @@
+<?cs include:"rosfooter.cs"?>
</body>
</html>
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topic.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topic.cs 2009-09-02 08:35:18 UTC (rev 23683)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topic.cs 2009-09-02 08:48:31 UTC (rev 23684)
@@ -13,8 +13,7 @@
<div style="border: 2px solid white; font-size: 10pt; font-family: courier; height: 40em; width: 60em;" objtype=ScrollingTextWidget topic="<?cs var:CGI.cur.topic ?>"></div><br>
<br>
-<div id=ErrorDiv></div>
-
+<?cs include:"rosfooter.cs"?>
</body>
</html>
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topics.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topics.cs 2009-09-02 08:35:18 UTC (rev 23683)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topics.cs 2009-09-02 08:48:31 UTC (rev 23684)
@@ -1,7 +1,7 @@
<html>
<head>
<?cs include:"includes.cs" ?>
-</head>
+ </head>
<body onload="ros_handleOnLoad('/ros')">
<?cs include:"header.cs" ?>
@@ -21,5 +21,6 @@
<br>
+<?cs include:"rosfooter.cs"?>
</body>
</html>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rob...@us...> - 2009-09-02 21:04:45
|
Revision: 23709
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=23709&view=rev
Author: rob_wheeler
Date: 2009-09-02 21:04:37 +0000 (Wed, 02 Sep 2009)
Log Message:
-----------
add ability to set the pose
Modified Paths:
--------------
pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py
pkg/trunk/sandbox/web/navigation_application/jslib/map_viewer.js
Modified: pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py
===================================================================
--- pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py 2009-09-02 20:42:48 UTC (rev 23708)
+++ pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py 2009-09-02 21:04:37 UTC (rev 23709)
@@ -1,5 +1,6 @@
#!/usr/bin/env python
+import math
import rospy
import rosservice
import Image
@@ -9,15 +10,17 @@
import tf
import tf.transformations
-from geometry_msgs.msg import PoseStamped, Pose, Quaternion, Point
+from geometry_msgs.msg import PoseWithCovariance, PoseWithCovarianceStamped, PoseStamped, Pose, Quaternion, Point
+from numpy import float64
_map_cache = {}
_scale_cache = {}
_tile_cache = {}
def config_plugin():
- global goal_publisher
+ global goal_publisher, pose_publisher
goal_publisher = rospy.Publisher('/move_base/activate', PoseStamped)
+ pose_publisher = rospy.Publisher('/initialpose', PoseWithCovarianceStamped)
return [{'url': '/map', 'handler': map_tiler_handler}]
def get_map(service_name):
@@ -87,20 +90,36 @@
jpeg = base64.decodestring(unavail.unavail)
send_image(self, jpeg)
-def set_goal_handler(self, path, qdict):
+def get_pose(self, qdict):
x = float(qdict.get('x', [0])[0])
y = float(qdict.get('y', [0])[0])
angle = float(qdict.get('angle', [0])[0])
+ p = Point(x, y, 0)
+ q = tf.transformations.quaternion_from_euler(0, 0, angle)
+ q = Quaternion(q[0], q[1], q[2], q[3])
+ return Pose(p, q)
+
+def set_goal_handler(self, path, qdict):
+ pose = get_pose(self, qdict)
h = rospy.Header()
h.stamp= rospy.get_rostime()
h.frame_id = '/map'
- p = Point(x, y, 0)
- q = tf.transformations.quaternion_from_euler(0, 0, angle)
- q = Quaternion(q[0], q[1], q[2], q[3])
- goal = PoseStamped(h, Pose(p, q))
+ goal = PoseStamped(h, pose)
goal_publisher.publish(goal)
self.send_success()
+def set_pose_handler(self, path, qdict):
+ pose = get_pose(self, qdict)
+ h = rospy.Header()
+ h.stamp= rospy.get_rostime()
+ h.frame_id = '/map'
+ cov = [float64(0)] * 36
+ cov[6*0+0] = 0.5 * 0.5;
+ cov[6*1+1] = 0.5 * 0.5;
+ cov[6*3+3] = math.pi/12.0 * math.pi/12.0;
+ pose_publisher.publish(PoseWithCovarianceStamped(h, PoseWithCovariance(pose, cov)))
+ self.send_success()
+
def get_extents_handler(self, path, qdict):
service_name = qdict.get('service', ['static_map'])[0]
callback = qdict.get("callback", [''])[0]
@@ -121,6 +140,8 @@
get_extents_handler(self, path, qdict)
elif path == '/map/set_goal':
set_goal_handler(self, path, qdict)
+ elif path == '/map/set_pose':
+ set_pose_handler(self, path, qdict)
else:
return False
return True
Modified: pkg/trunk/sandbox/web/navigation_application/jslib/map_viewer.js
===================================================================
--- pkg/trunk/sandbox/web/navigation_application/jslib/map_viewer.js 2009-09-02 20:42:48 UTC (rev 23708)
+++ pkg/trunk/sandbox/web/navigation_application/jslib/map_viewer.js 2009-09-02 21:04:37 UTC (rev 23709)
@@ -46,8 +46,9 @@
initialize: function(domobj) {
this.viewer = domobj;
//this.topics = ['/robot_pose_visualization', '/move_base/NavfnROS/plan'];
+ this.topics = ['/robot_pose_visualization', '/simple_plan'];
//this.topics = ['/robot_pose_visualization', '/move_base/TrajectoryPlannerROS/robot_footprint'];
- this.topics = ['/robot_pose_visualization'];
+ //this.topics = ['/robot_pose_visualization'];
},
init: function() {
@@ -105,7 +106,10 @@
if (Event.isLeftClick(e)) {
this.panning = true;
} else if (Event.isMiddleClick(e)) {
- this.settingGoal = true;
+ if (e.ctrlKey)
+ this.settingPose = true;
+ else
+ this.settingGoal = true;
}
},
@@ -113,18 +117,21 @@
if (Event.isLeftClick(e)) {
this.panning = false;
} else if (Event.isMiddleClick(e)) {
- this.settingGoal = false;
- var dx = Event.pointerX(e) - this.mark[0];
- var dy = Event.pointerY(e) - this.mark[1];
- var angle = Math.atan2(-dy, dx);
- var off = this.viewer.cumulativeOffset();
- var pos = this.pixelToMap([this.mark[0]-off.left, this.mark[1]-off.top]);
- var url = 'http://' + window.location.hostname + ':8080';
- url += '/map/set_goal';
- url += '?x=' + pos.x;
- url += '&y=' + pos.y;
- url += '&angle=' + angle;
- getDataFromServer('_set_goal_pump', url);
+ if (this.settingGoal || this.settingPose) {
+ var dx = Event.pointerX(e) - this.mark[0];
+ var dy = Event.pointerY(e) - this.mark[1];
+ var angle = Math.atan2(-dy, dx);
+ var off = this.viewer.cumulativeOffset();
+ var pos = this.pixelToMap([this.mark[0]-off.left, this.mark[1]-off.top]);
+ var url = 'http://' + window.location.hostname + ':8080';
+ url += this.settingGoal ? '/map/set_goal' : '/map/set_pose';
+ url += '?x=' + pos.x;
+ url += '&y=' + pos.y;
+ url += '&angle=' + angle;
+ getDataFromServer('_set_goal_pump', url);
+ this.settingGoal = false;
+ this.settingPose = false;
+ }
}
},
@@ -302,8 +309,8 @@
this.robot = {'x': msg.pose.position.x,
'y': msg.pose.position.y,
'angle': angle};
- } else if (topic == '/move_base/NavfnROS/plan') {
- ros_debug('new plan: ' + msg.poses.length + ' poses');
+ } else if (topic == '/move_base/NavfnROS/plan' ||
+ topic == '/simple_plan') {
this.plan = msg.poses;
} else if (topic == '/move_base/TrajectoryPlannerROS/robot_footprint') {
this.footprint = msg.polygon.points;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wgh...@us...> - 2009-09-02 22:58:13
|
Revision: 23718
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=23718&view=rev
Author: wghassan
Date: 2009-09-02 22:58:05 +0000 (Wed, 02 Sep 2009)
Log Message:
-----------
added subtopics
Modified Paths:
--------------
pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py
pkg/trunk/sandbox/web/rosweb2/manifest.xml
pkg/trunk/sandbox/web/rosweb2/src/rosweb.py
pkg/trunk/sandbox/web/sample_application/manifest.xml
pkg/trunk/sandbox/web/sample_application/templates/index.cs
Added Paths:
-----------
pkg/trunk/sandbox/web/sample_application/src/
pkg/trunk/sandbox/web/sample_application/src/sample_application/
pkg/trunk/sandbox/web/sample_application/src/sample_application/__init__.py
pkg/trunk/sandbox/web/sample_application/src/sample_application/webhandler.py
Modified: pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py
===================================================================
--- pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py 2009-09-02 22:48:44 UTC (rev 23717)
+++ pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py 2009-09-02 22:58:05 UTC (rev 23718)
@@ -17,12 +17,13 @@
_scale_cache = {}
_tile_cache = {}
-def config_plugin():
+def config_plugin(context):
global goal_publisher, pose_publisher
goal_publisher = rospy.Publisher('/move_base/activate', PoseStamped)
pose_publisher = rospy.Publisher('/initialpose', PoseWithCovarianceStamped)
- return [{'url': '/map', 'handler': map_tiler_handler}]
+ context.register_handler("/map", map_tiler_handler)
+
def get_map(service_name):
map_key = service_name
if not _map_cache.has_key(map_key):
Modified: pkg/trunk/sandbox/web/rosweb2/manifest.xml
===================================================================
--- pkg/trunk/sandbox/web/rosweb2/manifest.xml 2009-09-02 22:48:44 UTC (rev 23717)
+++ pkg/trunk/sandbox/web/rosweb2/manifest.xml 2009-09-02 22:58:05 UTC (rev 23718)
@@ -15,6 +15,7 @@
<depend package="rospy"/>
<depend package="rosservice"/>
<depend package="rosjson"/>
+ <depend package="std_msgs"/>
</package>
Modified: pkg/trunk/sandbox/web/rosweb2/src/rosweb.py
===================================================================
--- pkg/trunk/sandbox/web/rosweb2/src/rosweb.py 2009-09-02 22:48:44 UTC (rev 23717)
+++ pkg/trunk/sandbox/web/rosweb2/src/rosweb.py 2009-09-02 22:58:05 UTC (rev 23718)
@@ -1,4 +1,8 @@
#!/usr/bin/env python
+"""
+usage: %(progname)s [--debug]
+"""
+
# Software License Agreement (BSD License)
#
# Copyright (c) 2009, Willow Garage, Inc.
@@ -36,6 +40,7 @@
PKG_NAME = 'rosweb2'
import roslib; roslib.load_manifest(PKG_NAME)
+import getopt
import cStringIO
import os
import signal
@@ -65,20 +70,22 @@
class ROSWebException(Exception): pass
def splitTopic(topic):
- parts = topic.split("/")
- topic = "/" + parts[1]
+ parts = topic.split(":", 1)
+ topic = parts[0]
subtopic = None
- if len(parts) == 3:
- subtopic = parts[2]
+ if len(parts) == 2:
+ subtopic = parts[1]
return topic, subtopic
## Factory for ROSWebTopic instances
class RWTFactory(object):
- def __init__(self):
+ def __init__(self, webserver):
self.map = {}
self.lock = threading.Lock()
+ self.webserver = webserver
+
self.counter = 1
self.cond = threading.Condition()
@@ -104,7 +111,7 @@
def subscribe(self, topic):
# Don't use 'subtopics' as they are currently implemented
# because the nav stack has topic names with '/' in them.
- if 0:
+ if 1:
maintopic, subtopic = splitTopic(topic)
else:
maintopic = topic
@@ -118,7 +125,8 @@
self.map[maintopic] = main_rwt
rwt = main_rwt
if subtopic:
- rwt = ROSWebSubTopic(topic, self, main_rwt)
+ handlerClass = self.webserver._subtopics[topic]
+ rwt = handlerClass(topic, self, main_rwt)
self.map[topic] = rwt
finally:
self.lock.release()
@@ -218,22 +226,25 @@
def init(self):
pass
- def subtopic_callback(self, data):
+ def subtopic_callback(self, msg):
## no locks needed since this will be called from the main topic
- if self.maintopic == "/diagnostics":
- for _msg in data.status:
- if _msg.name == self.subtopic:
- self.messages.append((self.factory.counter, data))
- self.factory.counter = self.factory.counter + 1
- self.messages = self.messages[-20:]
+ newmsg = self.transform(msg)
+ if not newmsg: return
+
+ self.messages.append((self.factory.counter, newmsg))
+ self.factory.counter = self.factory.counter + 1
+ self.newmsg = self.messages[-20:]
+
+
class VirtualTopic(object):
- def __init__(self, topic, factory, thread):
+ def __init__(self, topic, factory, thread, intopics=[]):
self.factory = factory
self.topic = topic
+ self.intopics = intopics
self.messages = []
@@ -242,6 +253,9 @@
def init(self):
if not self.initialized:
+ for _topic in self.intopics:
+ self.factory.subscribe(_topic)
+
self.initialized = True
self.thread.setCallback(self.callback)
self.thread.start()
@@ -269,6 +283,7 @@
rwt.init()
except ROSWebException, e:
self.server.factory.unsubscribe(topic)
+ logging.warning("Cannot subscribe to %s" % topic)
#traceback.print_exc()
return None
return rwt
@@ -276,9 +291,6 @@
def _do_GET_topic(self, topics, since, callback=None):
rwttopics = []
-# if "/topics" not in topics:
-# topics.append("/topics")
-
for topic in topics:
rwt = self.server.factory.get(topic)
if rwt:
@@ -291,7 +303,31 @@
logging.warning("no valid topics")
self.send_failure()
return
+
+ (messages, lastSince) = self._get_messages(rwttopics, since)
+
+ buf = cStringIO.StringIO()
+ buf.write("{")
+ buf.write('"since": %s,' % lastSince)
+ buf.write('"msgs": [')
+ _i = 0
+ for (topic, msg) in messages:
+ _i = _i + 1
+ if _i > 1: buf.write(',')
+ buf.write("{")
+ buf.write('"topic": "%s",' % topic)
+ buf.write('"msg": ')
+ buf.write(rosjson.ros_message_to_json(msg))
+ buf.write("}")
+ buf.write(']')
+ buf.write('}')
+ buf = buf.getvalue()
+
+ self.send_success(buf, callback)
+
+
+ def _get_messages(self, rwttopics, since):
messages = []
lastSince = 0
try:
@@ -325,27 +361,9 @@
lastSince = max(t, lastSince)
finally:
self.server.factory.cond.release()
+ return (messages, lastSince)
- buf = cStringIO.StringIO()
- buf.write("{")
- buf.write('"since": %s,' % lastSince)
- buf.write('"msgs": [')
- _i = 0
- for (topic, msg) in messages:
- _i = _i + 1
- if _i > 1: buf.write(',')
- buf.write("{")
- buf.write('"topic": "%s",' % topic)
- buf.write('"msg": ')
- buf.write(rosjson.ros_message_to_json(msg))
- buf.write("}")
- buf.write(']')
- buf.write('}')
-
- buf = buf.getvalue()
- self.send_success(buf, callback)
-
def _connect_to(self, netloc, soc):
i = netloc.find(':')
if i >= 0:
@@ -479,8 +497,7 @@
self.log_request()
- global handlers
- for handler in handlers:
+ for handler in self.server._handlers:
if path.startswith(handler['url']):
handler['handler'](self, path, qdict)
return
@@ -563,13 +580,43 @@
threading.Thread.__init__(self)
SocketServer.TCPServer.__init__(self, hostport, handlerClass)
- self.factory = RWTFactory()
-
- self.registerVirtualTopics()
+ self.factory = RWTFactory(self)
self.accesslog_fp = open("access_log", "a+")
- def registerVirtualTopics(self):
+ self._handlers = []
+ self.register_handler('/ros', ROSWebHandler.handle_ROS)
+
+ self._subtopics = {}
+
+ self.__load_plugins()
+ self.__registerVirtualTopics()
+
+ def register_handler(self, urlprefix, handler):
+ h = {'url': urlprefix, 'handler': handler}
+ self._handlers.append(h)
+
+ def register_subtopic(self, topic, handlerClass):
+ self._subtopics[topic] = handlerClass
+
+ def __load_plugins(self):
+ plugins = roslib.scriptutil.rospack_plugins(PKG_NAME)
+ for (package, plugin) in plugins:
+ try:
+ roslib.load_manifest(package)
+ mods = plugin.split('.')
+ mod = __import__(plugin)
+ for sub_mod in mods[1:]:
+ mod = getattr(mod, sub_mod)
+
+ mod.config_plugin(self)
+
+ except Exception, reason:
+ logging.error("got exception %s" % reason)
+ sys.exit(-1)
+
+
+ def __registerVirtualTopics(self):
import users
ut = users.UsersThread()
ut.setDaemon(True)
@@ -589,6 +636,7 @@
mm = None
web_server = ThreadingHTTPServer(('', 8080), ROSWebHandler)
+
web_server.setDaemon(True)
web_server.start()
logging.info("starting Web server")
@@ -609,34 +657,31 @@
global running
running = False
-handlers = [{'url': '/ros', 'handler': ROSWebHandler.handle_ROS}]
-def load_plugins():
- global handlers
- plugins = roslib.scriptutil.rospack_plugins(PKG_NAME)
- for (package, plugin) in plugins:
- try:
- roslib.load_manifest(package)
- mods = plugin.split('.')
- mod = __import__(plugin)
- for sub_mod in mods[1:]:
- mod = getattr(mod, sub_mod)
+def usage(progname):
+ print __doc__ % vars()
- h = mod.config_plugin()
- logging.info("Added handlers %s" % (h))
- handlers.extend(h)
-
- except Exception, reason:
- logging.error("got exception %s" % reason)
- sys.exit(-1)
+def main(argv, stdout, environ):
+ progname = argv[0]
+ optlist, args = getopt.getopt(argv[1:], "", ["help", "debug"])
-def main():
+ debugFlag = False
+ for (field, val) in optlist:
+ if field == "--help":
+ usage(progname)
+ return
+ elif field == "--debug":
+ debugFlag = True
+
global running, error_log
running = True
- logging.basicConfig(filename="error_log", level=logging.DEBUG)
+ if debugFlag:
+ logging.basicConfig(level=logging.DEBUG)
+ pass
+ else:
+ logging.basicConfig(filename="error_log", level=logging.DEBUG)
signal.signal(signal.SIGINT, signal_handler)
- load_plugins()
while running:
logging.info("starting")
@@ -644,12 +689,10 @@
rosweb_start()
except:
import traceback
- fp = open("error_log", "a+")
- traceback.print_exc(file=fp)
- fp.close()
+ traceback.print_exc()
time.sleep(1)
if error_log_fp: error_log_fp.close()
if __name__ == '__main__':
- main()
+ main(sys.argv, sys.stdout, os.environ)
Modified: pkg/trunk/sandbox/web/sample_application/manifest.xml
===================================================================
--- pkg/trunk/sandbox/web/sample_application/manifest.xml 2009-09-02 22:48:44 UTC (rev 23717)
+++ pkg/trunk/sandbox/web/sample_application/manifest.xml 2009-09-02 22:58:05 UTC (rev 23718)
@@ -9,6 +9,11 @@
<depend package="roslib"/>
<depend package="rospy"/>
<depend package="webui"/>
+ <depend package="rosweb2"/>
+ <depend package="std_msgs"/>
+ <export>
+ <rosweb2 plugin="sample_application.webhandler"/>
+ </export>
</package>
Added: pkg/trunk/sandbox/web/sample_application/src/sample_application/webhandler.py
===================================================================
--- pkg/trunk/sandbox/web/sample_application/src/sample_application/webhandler.py (rev 0)
+++ pkg/trunk/sandbox/web/sample_application/src/sample_application/webhandler.py 2009-09-02 22:58:05 UTC (rev 23718)
@@ -0,0 +1,19 @@
+#! /usr/bin/env python
+
+import rospy
+import rosservice
+import cStringIO
+
+import rosweb
+from std_msgs.msg import String
+
+def config_plugin(context):
+ context.register_subtopic("/chatter:more", MoreChatterSubtopic)
+
+class MoreChatterSubtopic(rosweb.ROSWebSubTopic):
+ def __init__(self, topic, factory, main_rwt):
+ rosweb.ROSWebSubTopic.__init__(self, topic, factory, main_rwt)
+
+ def transform(self, msg):
+ newmsg = String(msg.data.upper())
+ return newmsg
Property changes on: pkg/trunk/sandbox/web/sample_application/src/sample_application/webhandler.py
___________________________________________________________________
Added: svn:executable
+ *
Modified: pkg/trunk/sandbox/web/sample_application/templates/index.cs
===================================================================
--- pkg/trunk/sandbox/web/sample_application/templates/index.cs 2009-09-02 22:48:44 UTC (rev 23717)
+++ pkg/trunk/sandbox/web/sample_application/templates/index.cs 2009-09-02 22:58:05 UTC (rev 23718)
@@ -17,7 +17,7 @@
<table width=80% align=center>
<tr>
<td>
-<div style="align: center; border: 1px solid black; font-size: 10pt; font-family: courier; height: 40em; width: 60em;" objtype=TerminalTextWidget topic="/chatter" key="data"></div><br>
+<div style="align: center; border: 1px solid black; font-size: 10pt; font-family: courier; height: 40em; width: 60em;" objtype=TerminalTextWidget topic="/chatter:more" key="data"></div><br>
</td>
</table>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rob...@us...> - 2009-09-03 00:01:48
|
Revision: 23726
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=23726&view=rev
Author: rob_wheeler
Date: 2009-09-03 00:01:34 +0000 (Thu, 03 Sep 2009)
Log Message:
-----------
Add plan simplifier as a virtual subtopic.
Show robot position and orientation when setting goal or pose.
Modified Paths:
--------------
pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py
pkg/trunk/sandbox/web/navigation_application/jslib/map_viewer.js
Added Paths:
-----------
pkg/trunk/sandbox/web/map_tiler/src/map_tiler/simplify.py
Modified: pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py
===================================================================
--- pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py 2009-09-02 23:47:30 UTC (rev 23725)
+++ pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py 2009-09-03 00:01:34 UTC (rev 23726)
@@ -13,6 +13,8 @@
from geometry_msgs.msg import PoseWithCovariance, PoseWithCovarianceStamped, PoseStamped, Pose, Quaternion, Point
from numpy import float64
+from simplify import Simplifier
+
_map_cache = {}
_scale_cache = {}
_tile_cache = {}
@@ -23,6 +25,7 @@
pose_publisher = rospy.Publisher('/initialpose', PoseWithCovarianceStamped)
context.register_handler("/map", map_tiler_handler)
+ context.register_subtopic("/move_base/NavfnROS/plan:simplified", Simplifier)
def get_map(service_name):
map_key = service_name
Added: pkg/trunk/sandbox/web/map_tiler/src/map_tiler/simplify.py
===================================================================
--- pkg/trunk/sandbox/web/map_tiler/src/map_tiler/simplify.py (rev 0)
+++ pkg/trunk/sandbox/web/map_tiler/src/map_tiler/simplify.py 2009-09-03 00:01:34 UTC (rev 23726)
@@ -0,0 +1,77 @@
+#!/usr/bin/env python
+
+import rosweb
+
+from nav_msgs.msg import Path
+
+import math
+import time
+
+class Simplifier(rosweb.ROSWebSubTopic):
+ def __init__(self, topic, factory, main_rwt):
+ rosweb.ROSWebSubTopic.__init__(self, topic, factory, main_rwt)
+
+ def simplify_points (self, pts, tolerance):
+ anchor = 0
+ floater = len(pts) - 1
+ stack = []
+ keep = set()
+
+ stack.append((anchor, floater))
+ while stack:
+ anchor, floater = stack.pop()
+
+ # initialize line segment
+ if pts[floater] != pts[anchor]:
+ anchorX = float(pts[floater].pose.position.x - pts[anchor].pose.position.x)
+ anchorY = float(pts[floater].pose.position.y - pts[anchor].pose.position.y)
+ seg_len = math.sqrt(anchorX ** 2 + anchorY ** 2)
+ # get the unit vector
+ anchorX /= seg_len
+ anchorY /= seg_len
+ else:
+ anchorX = anchorY = seg_len = 0.0
+
+ # inner loop:
+ max_dist = 0.0
+ farthest = anchor + 1
+ for i in range(anchor + 1, floater):
+ dist_to_seg = 0.0
+ # compare to anchor
+ vecX = float(pts[i].pose.position.x - pts[anchor].pose.position.x)
+ vecY = float(pts[i].pose.position.y - pts[anchor].pose.position.y)
+ seg_len = math.sqrt( vecX ** 2 + vecY ** 2 )
+ # dot product:
+ proj = vecX * anchorX + vecY * anchorY
+ if proj < 0.0:
+ dist_to_seg = seg_len
+ else:
+ # compare to floater
+ vecX = float(pts[i].pose.position.x - pts[floater].pose.position.x)
+ vecY = float(pts[i].pose.position.y - pts[floater].pose.position.y)
+ seg_len = math.sqrt( vecX ** 2 + vecY ** 2 )
+ # dot product:
+ proj = vecX * (-anchorX) + vecY * (-anchorY)
+ if proj < 0.0:
+ dist_to_seg = seg_len
+ else: # calculate perpendicular distance to line (pythagorean theorem):
+ dist_to_seg = math.sqrt(abs(seg_len ** 2 - proj ** 2))
+ if max_dist < dist_to_seg:
+ max_dist = dist_to_seg
+ farthest = i
+
+ if max_dist <= tolerance: # use line segment
+ keep.add(anchor)
+ keep.add(floater)
+ else:
+ stack.append((anchor, farthest))
+ stack.append((farthest, floater))
+
+ keep = list(keep)
+ keep.sort()
+ return [pts[i] for i in keep]
+
+ def transform(self, msg):
+ newmsg = Path()
+ newmsg.poses = self.simplify_points(msg.poses, 0.05)
+ return newmsg
Property changes on: pkg/trunk/sandbox/web/map_tiler/src/map_tiler/simplify.py
___________________________________________________________________
Added: svn:executable
+ *
Modified: pkg/trunk/sandbox/web/navigation_application/jslib/map_viewer.js
===================================================================
--- pkg/trunk/sandbox/web/navigation_application/jslib/map_viewer.js 2009-09-02 23:47:30 UTC (rev 23725)
+++ pkg/trunk/sandbox/web/navigation_application/jslib/map_viewer.js 2009-09-03 00:01:34 UTC (rev 23726)
@@ -45,8 +45,8 @@
var MapViewer = Class.create({
initialize: function(domobj) {
this.viewer = domobj;
+ this.topics = ['/robot_pose_visualization', '/move_base/NavfnROS/plan:simplified'];
//this.topics = ['/robot_pose_visualization', '/move_base/NavfnROS/plan'];
- this.topics = ['/robot_pose_visualization', '/simple_plan'];
//this.topics = ['/robot_pose_visualization', '/move_base/TrajectoryPlannerROS/robot_footprint'];
//this.topics = ['/robot_pose_visualization'];
},
@@ -131,6 +131,7 @@
getDataFromServer('_set_goal_pump', url);
this.settingGoal = false;
this.settingPose = false;
+ delete this.robot_est;
}
}
},
@@ -141,6 +142,14 @@
this.mark = [Event.pointerX(e), Event.pointerY(e)];
this.panMap(this.mark[0] - old_mark[0],
this.mark[1] - old_mark[1]);
+ } else if (this.settingGoal || this.settingPose) {
+ var off = this.viewer.cumulativeOffset();
+ var pos = this.pixelToMap([this.mark[0]-off.left, this.mark[1]-off.top]);
+ var dx = Event.pointerX(e) - this.mark[0];
+ var dy = Event.pointerY(e) - this.mark[1];
+ var angle = Math.atan2(-dy, dx);
+ this.robot_est = {'x': pos.x, 'y': pos.y, 'angle': angle};
+ this.updateCanvas();
}
},
@@ -253,6 +262,17 @@
ctx.drawImage(this.robot_img, -this.robot_img.width / 2, -this.robot_img.height / 2);
ctx.restore();
}
+ if (this.robot_est) {
+ var coords = this.mapToPixel(this.robot_est);
+ ctx.save();
+ ctx.translate(coords[0], coords[1]);
+ ctx.rotate(-this.robot_est.angle);
+ var sx = 0.65 / (this.robot_img.width * this.sourceResolution * this.scale);
+ var sy = 0.65 / (this.robot_img.height * this.sourceResolution * this.scale);
+ ctx.scale(sx, sy);
+ ctx.drawImage(this.robot_img, -this.robot_img.width / 2, -this.robot_img.height / 2);
+ ctx.restore();
+ }
// Draw plan
if (this.plan) {
@@ -310,7 +330,7 @@
'y': msg.pose.position.y,
'angle': angle};
} else if (topic == '/move_base/NavfnROS/plan' ||
- topic == '/simple_plan') {
+ topic == '/move_base/NavfnROS/plan:simplified') {
this.plan = msg.poses;
} else if (topic == '/move_base/TrajectoryPlannerROS/robot_footprint') {
this.footprint = msg.polygon.points;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wgh...@us...> - 2009-09-04 05:24:55
|
Revision: 23816
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=23816&view=rev
Author: wghassan
Date: 2009-09-04 05:24:42 +0000 (Fri, 04 Sep 2009)
Log Message:
-----------
removed the app_update message to improve status updates
Modified Paths:
--------------
pkg/trunk/sandbox/web/launchman/src/launchman.py
pkg/trunk/sandbox/web/webui/src/webui/cgistarter.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/apps.py
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros_toolbar.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/apps.cs
Added Paths:
-----------
pkg/trunk/sandbox/web/navigation_application/src/navigation_application/__init__.py
Modified: pkg/trunk/sandbox/web/launchman/src/launchman.py
===================================================================
--- pkg/trunk/sandbox/web/launchman/src/launchman.py 2009-09-04 04:33:45 UTC (rev 23815)
+++ pkg/trunk/sandbox/web/launchman/src/launchman.py 2009-09-04 05:24:42 UTC (rev 23816)
@@ -84,7 +84,9 @@
loader.load(fn, config)
except:
self.task.status = "error"
- self.manager.app_update.publish(self.task)
+ #self.manager.app_update.publish(self.task)
+ self.manager._send_status()
+
return
self.runner = ROSLaunchRunner(rospy.get_param("/run_id"), config, is_core=False)
@@ -167,12 +169,13 @@
runner.task.started = rospy.get_rostime()
runner.task.status = "starting"
- self.app_update.publish(runner.task)
+# self.app_update.publish(runner.task)
+ self._send_status()
runner.launch()
runner.task.status = "running"
- self.app_update.publish(runner.task)
+# self.app_update.publish(runner.task)
self._send_status()
return StartTaskResponse("done")
@@ -184,7 +187,8 @@
def _stopTask(self, runner):
runner.task.status = "stopping"
- self.app_update.publish(runner.task)
+# self.app_update.publish(runner.task)
+ self._send_status()
for cgroup in runner.childGroups[:]:
self._stopTask(cgroup)
@@ -192,7 +196,8 @@
runner.stop()
runner.task.status = "stopped"
- self.app_update.publish(runner.task)
+# self.app_update.publish(runner.task)
+ self._send_status()
if runner.app.depends:
pgroup = self._taskGroups.get(runner.app.depends, None)
@@ -221,8 +226,9 @@
return StopTaskResponse("done")
def status_update(self, req):
- for provides, runner in self._taskGroups.items():
- self.app_update.publish(runner.task)
+ self._send_status()
+# for provides, runner in self._taskGroups.items():
+# self.app_update.publish(runner.task)
return StatusUpdateResponse("done")
Modified: pkg/trunk/sandbox/web/webui/src/webui/cgistarter.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/cgistarter.py 2009-09-04 04:33:45 UTC (rev 23815)
+++ pkg/trunk/sandbox/web/webui/src/webui/cgistarter.py 2009-09-04 05:24:42 UTC (rev 23816)
@@ -100,7 +100,7 @@
else:
n = 0
- debug("self.path", self.path)
+ #warn("self.path", self.path)
if len(self.path) > 1:
module = self.path[n]
@@ -113,13 +113,13 @@
app = module
n = n + 1
- modpath = getPackagePath(module)
+ modpath = os.path.join(getPackagePath(module), "src")
#roslib.load_manifest(module)
- fn = apply(os.path.join, [modpath] + self.path[n:])
+ fn = apply(os.path.join, [modpath] + [module] + self.path[n:])
moduleRootPath = modpath
- handlerRoot = apply(os.path.join, [modpath, "cgibin"])
- moduleTemplatePath = apply(os.path.join, [modpath, "templates"])
+ handlerRoot = apply(os.path.join, [modpath, module, "cgibin"])
+ moduleTemplatePath = apply(os.path.join, [modpath, module, "templates"])
else:
moduleRootPath = apply(os.path.join, ["mod", module])
handlerRoot = apply(os.path.join, ["mod", module, "cgibin"])
@@ -130,7 +130,7 @@
systemTemplatePath = apply(os.path.join, [cwd, "mod", "webui", "templates"])
systemJLIBPath = apply(os.path.join, [cwd, "mod", "webui", "jslib"])
- debug("fn", fn)
+ #warn("fn", fn)
## if requesting a file, then just output it to the browser.
if os.path.isfile(fn):
@@ -141,7 +141,7 @@
if modpath: sys.path.insert(0, os.path.abspath(modpath))
sys.path.insert(0, os.path.abspath(moduleRootPath))
- debug("sys.path", sys.path)
+ #debug("sys.path", sys.path)
handlerPath = ''
@@ -169,8 +169,9 @@
else:
modulePath, moduleFilename = os.path.split(handlerPath)
- debug(handlerPath, pathinfo)
- #warn("PATH", handlerPath, pathinfo, modulePath, moduleFilename)
+ #debug(handlerPath, pathinfo)
+ #warn("handlerRoot", handlerRoot)
+ #warn("handlerPath", handlerPath, "pathinfo", pathinfo, "modulePath", modulePath, "moduleFilename", moduleFilename)
#warn("PATH", self.path)
if not os.path.isfile(handlerPath):
@@ -183,7 +184,7 @@
#module = __import__(moduleName)
if app:
- module = __import__("cgibin.%s" % (moduleName, ), {}, {}, (None,))
+ module = __import__("%s.cgibin.%s" % (module, moduleName, ), {}, {}, (None,))
else:
module = __import__("mod.%s.cgibin.%s" % (module, moduleName), {}, {}, (None,))
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/apps.py
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/apps.py 2009-09-04 04:33:45 UTC (rev 23815)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/cgibin/apps.py 2009-09-04 05:24:42 UTC (rev 23816)
@@ -20,6 +20,8 @@
self.db = db_webui.initSchema()
def display(self, hdf):
+ db_webui.grabTopics(hdf, [])
+
hdf.setValue("CGI.now", str(time.time()))
apps = self.db.apps.fetchAllRows()
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js 2009-09-04 04:33:45 UTC (rev 23815)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js 2009-09-04 05:24:42 UTC (rev 23816)
@@ -223,6 +223,7 @@
gPump.evalMessages(window.gMessage);
}
gPump.pump();
+ gPump.service_call("status_update", []);
}
// *******************************************
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros_toolbar.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros_toolbar.js 2009-09-04 04:33:45 UTC (rev 23815)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros_toolbar.js 2009-09-04 05:24:42 UTC (rev 23816)
@@ -7,23 +7,40 @@
this.domobj = domobj;
this.taskid = domobj.getAttribute("taskid");
this.state = false;
- this.topics = [domobj.getAttribute("topic")];
+ this.topics = ["/app_update", "/app_status"];
},
init: function() {
var obj = this;
this.domobj.onmousedown = function() {obj.onmousedown();};
- if(this.state == true) {
- this.domobj.setAttribute("class", "buttonOn");
- } else {
- this.domobj.setAttribute("class", "buttonOff");
+ this.set_state();
+ },
+
+ set_state: function() {
+ var button = this.domobj;
+ if(button != null) {
+ this.domobj.style.border = "solid";
+ if(this.state == true) {
+ button.setAttribute("class", "buttonOn");
+ } else {
+ button.setAttribute("class", "buttonOff");
+ }
}
+ },
- //this.pump.service_call("status_update", []);
+ receive: function(topic, msg) {
+ if(topic == "/app_update") this.receive_app_update(msg);
+ else if(topic == "/app_status") this.receive_app_status(msg);
},
- receive: function(topic, msg) {
+ receive_app_status: function(msg) {
+ for(var i=0; i<msg.active.length; i++) {
+ this.receive_app_update(msg.active[i]);
+ }
+ },
+
+ receive_app_update: function(msg) {
if(msg.taskid != this.taskid) return;
var prev_state = this.state;
@@ -33,15 +50,7 @@
if(state == "stopped") this.state = false;
if(prev_state != this.state) {
- var button = this.domobj;
- if(button != null) {
- this.domobj.style.border = "solid";
- if(this.state == true) {
- button.setAttribute("class", "buttonOn");
- } else {
- button.setAttribute("class", "buttonOff");
- }
- }
+ this.set_state();
}
},
@@ -70,28 +79,57 @@
this.pump = null;
this.domobj = domobj;
this.taskid = domobj.getAttribute("taskid");
- this.state = false;
- this.topics = [domobj.getAttribute("topic")];
+ this.state = null;
+ this.topics = ["/app_status"];
+
+ this.button = null;
+ this.statusdiv = null;
},
init: function() {
var obj = this;
- this.domobj.onmousedown = function() {obj.onmousedown();};
+ this.domobj.innerHTML = '<input class=app_button type=button value="">\n<div class=app_status> </div>';
+ this.button = this.domobj.childNodes[0];
+ this.statusdiv = this.domobj.childNodes[2];
+
+ this.button.onmousedown = function() {obj.onmousedown();};
+
this.set_state();
},
receive: function(topic, msg) {
+ if(topic == "/app_update") this.receive_app_update(msg);
+ else if(topic == "/app_status") this.receive_app_status(msg);
+ },
+
+ receive_app_status: function(msg) {
+ var active = false;
+ for(var i=0; i<msg.active.length; i++) {
+ if(msg.active[i].taskid == this.taskid) {
+ this.receive_app_update(msg.active[i]);
+ active = true;
+ }
+ }
+ if(active == false) {
+ this.state = false;
+ this.set_state();
+ }
+ },
+
+ receive_app_update: function(msg) {
if(msg.taskid != this.taskid) return;
var prev_state = this.state;
+ this.statusdiv.innerHTML = msg.status;
+
var state = msg.status;
if(state == "running") this.state = true;
if(state == "stopped") this.state = false;
if(prev_state != this.state) {
- this.set_state(this.state);
+ this.set_state();
}
},
@@ -99,14 +137,14 @@
if(this.domobj == null) return;
if(this.state == true) {
- // this.domobj.disabled = 0;
- this.domobj.value = "Stop";
+ this.button.disabled = 0;
+ this.button.value = "Stop";
} else if (this.state == false) {
- // this.domobj.disabled = 0;
- this.domobj.value = "Launch";
+ this.button.disabled = 0;
+ this.button.value = "Launch";
} else {
- this.domobj.disabled = 1;
- this.domobj.value = "";
+ this.button.disabled = 1;
+ this.button.value = "";
}
},
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/apps.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/apps.cs 2009-09-04 04:33:45 UTC (rev 23815)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/apps.cs 2009-09-04 05:24:42 UTC (rev 23816)
@@ -29,8 +29,7 @@
<div class=app_description><?cs var:_app.description ?></div>
</td>
<td valign=top>
-<input class=app_button type=button value="" objtype="LaunchButtonWidget2" topic="/app_update" taskid="<?cs var:_app.taskid ?>">
-<div class=app_status objtype=TextWidget topic="/app_update" key=status selector="taskid" selectorValue="<?cs var:_app.taskid?>"> </div>
+<div class=app_button objtype="LaunchButtonWidget2" taskid="<?cs var:_app.taskid ?>">
</td>
</tr>
</table>
@@ -43,5 +42,6 @@
<div id=ErrorDiv></div>
+<?cs include:"rosfooter.cs"?>
</body>
</html>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wgh...@us...> - 2009-09-04 06:19:00
|
Revision: 23818
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=23818&view=rev
Author: wghassan
Date: 2009-09-04 06:18:52 +0000 (Fri, 04 Sep 2009)
Log Message:
-----------
fixed talker app
Modified Paths:
--------------
pkg/trunk/sandbox/web/launchman/src/launchman.py
pkg/trunk/sandbox/web/sample_application/src/sample_application/listener.py
pkg/trunk/sandbox/web/sample_application/src/sample_application/talker.py
pkg/trunk/sandbox/web/sample_application/src/sample_application/templates/index.cs
Modified: pkg/trunk/sandbox/web/launchman/src/launchman.py
===================================================================
--- pkg/trunk/sandbox/web/launchman/src/launchman.py 2009-09-04 05:28:37 UTC (rev 23817)
+++ pkg/trunk/sandbox/web/launchman/src/launchman.py 2009-09-04 06:18:52 UTC (rev 23818)
@@ -110,7 +110,14 @@
print "ALL DONE!"
self.manager._stopTask(self)
else:
- print "too many procs", self.runner.pm.procs
+ if self.runner.pm.procs:
+ self.task.status = "error"
+ self.manager._send_status()
+
+ print "too many processes left:", len(self.runner.pm.procs)
+ for proc in self.runner.pm.procs:
+ proc.stop()
+
self.runner = None
self.manager._stopTask(self)
@@ -196,7 +203,6 @@
runner.stop()
runner.task.status = "stopped"
-# self.app_update.publish(runner.task)
self._send_status()
if runner.app.depends:
Modified: pkg/trunk/sandbox/web/sample_application/src/sample_application/listener.py
===================================================================
--- pkg/trunk/sandbox/web/sample_application/src/sample_application/listener.py 2009-09-04 05:28:37 UTC (rev 23817)
+++ pkg/trunk/sandbox/web/sample_application/src/sample_application/listener.py 2009-09-04 06:18:52 UTC (rev 23818)
@@ -36,7 +36,7 @@
## Simple talker demo that listens to std_msgs/Strings published
## to the 'chatter' topic
-PKG = 'rospy_tutorials' # this package name
+PKG = 'sample_application' # this package name
import roslib; roslib.load_manifest(PKG)
import rospy
@@ -52,7 +52,7 @@
# anonymous=True flag means that rospy will choose a unique
# name for our 'talker' node so that multiple talkers can
# run simultaenously.
- rospy.init_node('listener', anonymous=True)
+ rospy.init_node('app_listener')
rospy.Subscriber("chatter", String, callback)
Modified: pkg/trunk/sandbox/web/sample_application/src/sample_application/talker.py
===================================================================
--- pkg/trunk/sandbox/web/sample_application/src/sample_application/talker.py 2009-09-04 05:28:37 UTC (rev 23817)
+++ pkg/trunk/sandbox/web/sample_application/src/sample_application/talker.py 2009-09-04 06:18:52 UTC (rev 23818)
@@ -36,20 +36,23 @@
## Simple talker demo that published std_msgs/Strings messages
## to the 'chatter' topic
-import roslib; roslib.load_manifest('rospy_tutorials')
+import roslib; roslib.load_manifest('sample_application')
import rospy
from std_msgs.msg import String
+import os, time
def talker():
pub = rospy.Publisher('chatter', String)
- rospy.init_node('talker', anonymous=True)
- r = rospy.Rate(1) # 10hz
+# rospy.init_node('talker', anonymous=True)
+ rospy.init_node('app_talker')
+ t = 0
while not rospy.is_shutdown():
- str = "hello world %s"%rospy.get_time()
+ str = "hello world %s %s" % (os.getpid(), t)
rospy.loginfo(str)
pub.publish(str)
- r.sleep()
+ time.sleep(1)
+ t = t + 1
if __name__ == '__main__':
try:
Modified: pkg/trunk/sandbox/web/sample_application/src/sample_application/templates/index.cs
===================================================================
--- pkg/trunk/sandbox/web/sample_application/src/sample_application/templates/index.cs 2009-09-04 05:28:37 UTC (rev 23817)
+++ pkg/trunk/sandbox/web/sample_application/src/sample_application/templates/index.cs 2009-09-04 06:18:52 UTC (rev 23818)
@@ -9,8 +9,7 @@
<table align=right>
<td>
-<input class=app_button type=button value="" objtype="LaunchButtonWidget2" topic="/app_update" taskid="<?cs var:CGI.cur.app.taskid ?>">
-<div class=app_status objtype=TextWidget topic="/app_update" key=status selector="taskid" selectorValue="<?cs var:CGI.cur.app.taskid?>"> </div>
+<div class=app_button objtype="LaunchButtonWidget2" taskid="<?cs var:CGI.cur.app.taskid ?>">
</td>
</table>
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <wgh...@us...> - 2009-09-04 07:47:45
|
Revision: 23824
http://personalrobots.svn.sourceforge.net/personalrobots/?rev=23824&view=rev
Author: wghassan
Date: 2009-09-04 07:47:36 +0000 (Fri, 04 Sep 2009)
Log Message:
-----------
fixes for the app bar
Modified Paths:
--------------
pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py
pkg/trunk/sandbox/web/navigation_application/src/navigation_application/jslib/map_viewer.js
pkg/trunk/sandbox/web/navigation_application/src/navigation_application/templates/index.cs
pkg/trunk/sandbox/web/rosweb2/src/rosweb.py
pkg/trunk/sandbox/web/sample_application/src/sample_application/cgibin/sample_application_index.py
pkg/trunk/sandbox/web/sample_application/src/sample_application/templates/index.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/header.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/nodes.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/powerboard.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/status.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topic.cs
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topics.cs
Added Paths:
-----------
pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/status_header.cs
Modified: pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py
===================================================================
--- pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py 2009-09-04 07:45:26 UTC (rev 23823)
+++ pkg/trunk/sandbox/web/map_tiler/src/map_tiler/handler.py 2009-09-04 07:47:36 UTC (rev 23824)
@@ -14,6 +14,7 @@
from numpy import float64
from simplify import Simplifier
+import rosweb
_map_cache = {}
_scale_cache = {}
Modified: pkg/trunk/sandbox/web/navigation_application/src/navigation_application/jslib/map_viewer.js
===================================================================
--- pkg/trunk/sandbox/web/navigation_application/src/navigation_application/jslib/map_viewer.js 2009-09-04 07:45:26 UTC (rev 23823)
+++ pkg/trunk/sandbox/web/navigation_application/src/navigation_application/jslib/map_viewer.js 2009-09-04 07:47:36 UTC (rev 23824)
@@ -45,8 +45,8 @@
var MapViewer = Class.create({
initialize: function(domobj) {
this.viewer = domobj;
- //this.topics = ['/robot_pose_visualization', '/move_base/NavfnROS/plan:simplified', '/base_pose_ground_truth'];
- this.topics = ['/robot_pose_visualization', '/move_base/NavfnROS/plan:simplified'];
+ this.topics = ['/robot_pose_visualization', '/move_base/NavfnROS/plan:simplified', '/base_pose_ground_truth'];
+ //this.topics = ['/robot_pose_visualization', '/move_base/NavfnROS/plan:simplified'];
},
buttons: [
Modified: pkg/trunk/sandbox/web/navigation_application/src/navigation_application/templates/index.cs
===================================================================
--- pkg/trunk/sandbox/web/navigation_application/src/navigation_application/templates/index.cs 2009-09-04 07:45:26 UTC (rev 23823)
+++ pkg/trunk/sandbox/web/navigation_application/src/navigation_application/templates/index.cs 2009-09-04 07:47:36 UTC (rev 23824)
@@ -11,8 +11,7 @@
<table align=right>
<td>
-<input class=app_button type=button value="" objtype="LaunchButtonWidget2" topic="/app_update" taskid="<?cs var:CGI.cur.app.taskid ?>">
-<div class=app_status objtype=TextWidget topic="/app_update" key=status selector="taskid" selectorValue="<?cs var:CGI.cur.app.taskid?>"> </div>
+<div class=app_button objtype="LaunchButtonWidget2" taskid="navigation_application/navigation_application.app">
</td>
</table>
Modified: pkg/trunk/sandbox/web/rosweb2/src/rosweb.py
===================================================================
--- pkg/trunk/sandbox/web/rosweb2/src/rosweb.py 2009-09-04 07:45:26 UTC (rev 23823)
+++ pkg/trunk/sandbox/web/rosweb2/src/rosweb.py 2009-09-04 07:47:36 UTC (rev 23824)
@@ -235,7 +235,7 @@
self.messages.append((self.factory.counter, newmsg))
self.factory.counter = self.factory.counter + 1
- self.newmsg = self.messages[-20:]
+ self.messages = self.messages[-20:]
Modified: pkg/trunk/sandbox/web/sample_application/src/sample_application/cgibin/sample_application_index.py
===================================================================
--- pkg/trunk/sandbox/web/sample_application/src/sample_application/cgibin/sample_application_index.py 2009-09-04 07:45:26 UTC (rev 23823)
+++ pkg/trunk/sandbox/web/sample_application/src/sample_application/cgibin/sample_application_index.py 2009-09-04 07:47:36 UTC (rev 23824)
@@ -11,12 +11,14 @@
from webui import MBPage
+import db_webui
+
class MyPage(MBPage.MBPage):
def setup(self, hdf):
pass
def display(self, hdf):
- pass
+ db_webui.grabTopics(hdf, ['/chatter:more'])
def run(context):
Modified: pkg/trunk/sandbox/web/sample_application/src/sample_application/templates/index.cs
===================================================================
--- pkg/trunk/sandbox/web/sample_application/src/sample_application/templates/index.cs 2009-09-04 07:45:26 UTC (rev 23823)
+++ pkg/trunk/sandbox/web/sample_application/src/sample_application/templates/index.cs 2009-09-04 07:47:36 UTC (rev 23824)
@@ -9,7 +9,7 @@
<table align=right>
<td>
-<div class=app_button objtype="LaunchButtonWidget2" taskid="<?cs var:CGI.cur.app.taskid ?>">
+<div class=app_button objtype="LaunchButtonWidget2" taskid="sample_application/sample_app.app">
</td>
</table>
@@ -22,5 +22,6 @@
<div id=ErrorDiv></div>
+<?cs include:"rosfooter.cs"?>
</body>
</html>
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js 2009-09-04 07:45:26 UTC (rev 23823)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/jslib/ros.js 2009-09-04 07:47:36 UTC (rev 23824)
@@ -392,8 +392,10 @@
new_message: function($super, msg) {
if(msg[this.key] != null) {
var d = document.createElement("div");
- d.innerHTML = msg[this.key] + "<br>";
+ d.appendChild(document.createTextNode(msg[this.key]));
+ d.innerHTML = msg[this.key];
this.textdiv.appendChild(d);
+
}
}
});
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/header.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/header.cs 2009-09-04 07:45:26 UTC (rev 23823)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/header.cs 2009-09-04 07:47:36 UTC (rev 23824)
@@ -20,13 +20,9 @@
</tr>
</table>
-<table class=head_buttons width=100%>
+<table class=head_buttons width=80%>
<tr>
<td class=head_buttons width=1% onclick="javascript:location.href='<?cs var:CGI.ScriptName?>/webui/apps.py'">Apps</a></td>
-<!--<td class=head_buttons width=1% onclick="javascript:location.href='<?cs var:CGI.ScriptName?>/webui/move.py'">Move</td> -->
-<td class=head_buttons width=1% onclick="javascript:location.href='<?cs var:CGI.ScriptName?>/webui/topics.py'">Topics</a></td>
-<td class=head_buttons width=1% onclick="javascript:location.href='<?cs var:CGI.ScriptName?>/webui/nodes.py'">Nodes</td>
-<td class=head_buttons width=1% onclick="javascript:location.href='<?cs var:CGI.ScriptName?>/webui/powerboard.py'">Power</td>
<td class=head_buttons width=1% onclick="javascript:location.href='<?cs var:CGI.ScriptName?>/webui/status.py'">Status</a></td>
<td class=head_buttons width=1% onclick="javascript:location.href='<?cs var:CGI.ScriptName?>/webui/admin.py'">Admin</a></td>
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/nodes.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/nodes.cs 2009-09-04 07:45:26 UTC (rev 23823)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/nodes.cs 2009-09-04 07:47:36 UTC (rev 23824)
@@ -6,6 +6,7 @@
<body onload="ros_handleOnLoad('/ros')">
<?cs include:"header.cs" ?>
<br>
+<?cs include:"status_header.cs" ?>
<h3>Nodes:</h3>
<ul objtype="ListWidget" topic="/topics" key="nodes">
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/powerboard.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/powerboard.cs 2009-09-04 07:45:26 UTC (rev 23823)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/powerboard.cs 2009-09-04 07:47:36 UTC (rev 23824)
@@ -11,6 +11,7 @@
<body onload="ros_handleOnLoad('/ros')">
<?cs include:"header.cs" ?>
<br>
+<?cs include:"status_header.cs" ?>
<br>
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/status.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/status.cs 2009-09-04 07:45:26 UTC (rev 23823)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/status.cs 2009-09-04 07:47:36 UTC (rev 23824)
@@ -6,7 +6,7 @@
<body onload="ros_handleOnLoad('/ros')">
<?cs include:"header.cs" ?>
<br>
-<br>
+<?cs include:"status_header.cs" ?>
<table style="border: 1px solid black; width: 150px; float: right">
<tr>
Added: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/status_header.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/status_header.cs (rev 0)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/status_header.cs 2009-09-04 07:47:36 UTC (rev 23824)
@@ -0,0 +1,8 @@
+<table class=head_buttons width=30%>
+<tr>
+<td class=head_buttons width=1% onclick="javascript:location.href='<?cs var:CGI.ScriptName?>/webui/topics.py'">Topics</a></td>
+<td class=head_buttons width=1% onclick="javascript:location.href='<?cs var:CGI.ScriptName?>/webui/nodes.py'">Nodes</td>
+<td class=head_buttons width=1% onclick="javascript:location.href='<?cs var:CGI.ScriptName?>/webui/powerboard.py'">Power</td>
+
+</tr>
+</table>
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topic.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topic.cs 2009-09-04 07:45:26 UTC (rev 23823)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topic.cs 2009-09-04 07:47:36 UTC (rev 23824)
@@ -6,6 +6,9 @@
<body onload="ros_handleOnLoad('/ros')">
<?cs include:"header.cs" ?>
+<br>
+<?cs include:"status_header.cs" ?>
+
<h3>Topic: <?cs var:CGI.cur.topic?></h3>
<div style="font-size: 10pt; " objtype=MessageWidget topic="<?cs var:CGI.cur.topic ?>"></div><br>
Modified: pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topics.cs
===================================================================
--- pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topics.cs 2009-09-04 07:45:26 UTC (rev 23823)
+++ pkg/trunk/sandbox/web/webui/src/webui/mod/webui/templates/topics.cs 2009-09-04 07:47:36 UTC (rev 23824)
@@ -6,6 +6,7 @@
<body onload="ros_handleOnLoad('/ros')">
<?cs include:"header.cs" ?>
<br>
+<?cs include:"status_header.cs" ?>
<h3>Published topics:</h3>
<ul objtype="ListWidget" topic="/topics" key="pubtopics">
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|