Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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
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
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 if (bad):
00208 self._load()
00209