app_list.py
Go to the documentation of this file.
00001 # Software License Agreement (BSD License)
00002 #
00003 # Copyright (c) 2011, Willow Garage, Inc.
00004 # All rights reserved.
00005 #
00006 # Redistribution and use in source and binary forms, with or without
00007 # modification, are permitted provided that the following conditions
00008 # are met:
00009 #
00010 #  * Redistributions of source code must retain the above copyright
00011 #    notice, this list of conditions and the following disclaimer.
00012 #  * Redistributions in binary form must reproduce the above
00013 #    copyright notice, this list of conditions and the following
00014 #    disclaimer in the documentation and/or other materials provided
00015 #    with the distribution.
00016 #  * Neither the name of Willow Garage, Inc. nor the names of its
00017 #    contributors may be used to endorse or promote products derived
00018 #    from this software without specific prior written permission.
00019 #
00020 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00021 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00022 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00023 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00024 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00025 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00026 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00027 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00030 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031 # POSSIBILITY OF SUCH DAMAGE.
00032 #
00033 # Revision $Id: topics.py 11753 2010-10-25 06:23:19Z kwc $
00034 
00035 # author: kwc
00036 
00037 """
00038 Implements applist part of app_manager, which handles listing of
00039 currently installed applications.
00040 """
00041 
00042 import os
00043 import sys
00044 import yaml
00045 
00046 from .app import load_AppDefinition_by_name
00047 from app_manager.msg import App, ClientApp, KeyValue, Icon
00048 from .exceptions import AppException, InvalidAppException
00049 
00050 import roslib
00051 roslib.load_manifest('turtlebot_app_manager')
00052 import rospy
00053 
00054 def get_default_applist_directory():
00055     """
00056     Default directory where applist configuration is stored.
00057     """
00058     return "/etc/robot/apps"
00059 
00060 def dict_to_KeyValue(d):
00061     l = []
00062     for k, v in d.iteritems():
00063         l.append(KeyValue(k, str(v)))
00064     return l
00065         
00066 def read_Icon_file(filename):
00067     icon = Icon()
00068     if filename == None or filename == "":
00069         return icon
00070     basename, extension = os.path.splitext(filename)
00071     if extension.lower() == ".jpg" or extension.lower() == ".jpeg":
00072         icon.format = "jpeg"
00073     elif extension.lower() == ".png":
00074         icon.format = "png"
00075     else:
00076         icon.format = ""
00077         return icon
00078     icon.data = open(filename, "rb").read()
00079     return icon
00080 
00081 def AppDefinition_to_App(app_definition):
00082     a = App(name=app_definition.name, display_name=app_definition.display_name, icon=read_Icon_file(app_definition.icon))
00083     a.client_apps = []
00084     for c in app_definition.clients:
00085         a.client_apps.append(ClientApp(c.client_type,
00086                                        dict_to_KeyValue(c.manager_data),
00087                                        dict_to_KeyValue(c.app_data)))
00088     return a
00089 
00090 class InstalledFile(object):
00091     """
00092     Models data stored in a .installed file.  These files are used to
00093     track installation of apps.
00094     """
00095     
00096     def __init__(self, filename):
00097         self.filename = filename
00098         # list of App
00099         self.available_apps = []
00100 
00101         self._file_mtime = None
00102         self.update()
00103 
00104     def _load(self):
00105         available_apps = []
00106         with open(self.filename) as f:
00107             installed_data = yaml.load(f)
00108             for reqd in ['apps']:
00109                 if not reqd in installed_data:
00110                     raise InvalidAppException("installed file [%s] is missing required key [%s]"%(self.filename, reqd))
00111             for app in installed_data['apps']:
00112                 for areqd in ['app']:
00113                     if not areqd in app:
00114                         raise InvalidAppException("installed file [%s] app definition is missing required key [%s]"%(self.filename, areqd))
00115                 available_apps.append(load_AppDefinition_by_name(app['app']))
00116                 
00117         self.available_apps = available_apps
00118 
00119     def update(self):
00120         """
00121         Update app list
00122         """
00123         s = os.stat(self.filename)
00124         if s.st_mtime != self._file_mtime:
00125             self._load()
00126             self._file_mtime = s.st_mtime
00127     
00128 class AppList(object):
00129     
00130     def __init__(self, applist_directories):
00131         self.applist_directories = applist_directories
00132         self.installed_files = {}
00133         self.invalid_installed_files = []
00134         self.app_list = []
00135         
00136         self._applist_directory_mtime = None
00137         self.update()
00138         
00139     def _load(self):
00140         app_list = []
00141         invalid_installed_files = []
00142         
00143         dir_list = [] 
00144         for i in self.applist_directories:
00145             for k in os.listdir(i):
00146                 dir_list.append(k)
00147             
00148         
00149         for f in set(self.installed_files.keys()) - set(dir_list):
00150             rospy.loginfo("App Manager: deleting installation data for [%s]"%(f))
00151             del self.installed_files[f]
00152         
00153         for i in self.applist_directories:
00154             for f in os.listdir(i):
00155                 rospy.loginfo("App Manager: found installed app list [%s]."%f)
00156                 if not f.endswith('.installed'):
00157                     continue
00158                 try:
00159                     if f in self.installed_files:
00160                         installed_file = self.installed_files[f]
00161                         installed_file.update()
00162                     else:
00163                         rospy.loginfo("App Manager: loading installation data for [%s]"%(f))
00164                         filename = os.path.join(i, f)
00165                         installed_file = InstalledFile(filename)
00166                         self.installed_files[f] = installed_file
00167                     
00168                     app_list.extend(installed_file.available_apps)
00169 
00170                 except AppException as ae:
00171                     print >> sys.stderr, "ERROR: %s"%(str(ae))
00172                     invalid_installed_files.append((filename, ae))
00173                 except Exception as e:
00174                     print >> sys.stderr, "ERROR: %s"%(str(e))
00175                     invalid_installed_files.append((filename, e))
00176 
00177         self.app_list = app_list
00178         self.invalid_installed_files = invalid_installed_files
00179         
00180     def get_app_list(self):
00181         return [AppDefinition_to_App(ad) for ad in self.app_list]
00182     
00183     def add_directory(self, directory):
00184         self.applist_directories.append(directory)
00185 
00186     def update(self):
00187         """
00188         Update app list
00189         """
00190         
00191         bad = True
00192         #TODO: this detects when the directories are actually modified.
00193         #It does not work because os.stat(i).st_mtime does not change if
00194         #only a file is modified.
00195         #s = []
00196         #for i in self.applist_directories:
00197         #    s.append(os.stat(i).st_mtime)
00198         #
00199         #bad = True
00200         #if self._applist_directory_mtime != None:
00201         #    if len(s) == len(self._applist_directory_mtime):
00202         #        bad = False
00203         #        for i in range(0, len(s)):
00204         #            if s[i] != self._applist_directory_mtime[i]:
00205         #                bad = True
00206         
00207         if (bad):
00208             self._load()
00209             #self._applist_directory_mtime = s


turtlebot_app_manager
Author(s): Jeremy Leibs, Ken Conley
autogenerated on Mon Oct 6 2014 08:00:31