app_list.py
Go to the documentation of this file.
1 # Software License Agreement (BSD License)
2 #
3 # Copyright (c) 2011, Willow Garage, Inc.
4 # All rights reserved.
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 #
10 # * Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # * Redistributions in binary form must reproduce the above
13 # copyright notice, this list of conditions and the following
14 # disclaimer in the documentation and/or other materials provided
15 # with the distribution.
16 # * Neither the name of Willow Garage, Inc. nor the names of its
17 # contributors may be used to endorse or promote products derived
18 # from this software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 # POSSIBILITY OF SUCH DAMAGE.
32 #
33 # Revision $Id: topics.py 11753 2010-10-25 06:23:19Z kwc $
34 
35 # author: kwc
36 
37 """
38 Implements applist part of app_manager, which handles listing of
39 currently installed applications.
40 """
41 
42 import os
43 import rospy
44 import sys
45 import yaml
46 
47 from .app import load_AppDefinition_by_name
48 from .msg import App, ClientApp, KeyValue, Icon
49 from .exceptions import AppException, InvalidAppException, NotFoundException
50 
52  """
53  Default directory where applist configuration is stored.
54  """
55  return "/etc/robot/apps"
56 
58  l = []
59  for k, v in d.items():
60  l.append(KeyValue(k, str(v)))
61  return l
62 
63 def read_Icon_file(filename):
64  icon = Icon()
65  if filename == None or filename == "":
66  return icon
67  basename, extension = os.path.splitext(filename)
68  if extension.lower() == ".jpg" or extension.lower() == ".jpeg":
69  icon.format = "jpeg"
70  elif extension.lower() == ".png":
71  icon.format = "png"
72  else:
73  icon.format = ""
74  return icon
75  icon.data = open(filename, "rb").read()
76  return icon
77 
78 def AppDefinition_to_App(app_definition):
79  a = App(name=app_definition.name, display_name=app_definition.display_name, icon=read_Icon_file(app_definition.icon))
80  a.client_apps = []
81  for c in app_definition.clients:
82  a.client_apps.append(ClientApp(c.client_type,
83  dict_to_KeyValue(c.manager_data),
84  dict_to_KeyValue(c.app_data)))
85  return a
86 
87 class InstalledFile(object):
88  """
89  Models data stored in a .installed file. These files are used to
90  track installation of apps.
91  """
92 
93  def __init__(self, filename):
94  self.filename = filename
95  # list of App
96  self.available_apps = []
97 
98  self._file_mtime = None
99  self.update()
100 
101  def _load(self):
102  available_apps = []
103  with open(self.filename) as f:
104  installed_data = yaml.load(f)
105  for reqd in ['apps']:
106  if not reqd in installed_data:
107  raise InvalidAppException("installed file [%s] is missing required key [%s]"%(self.filename, reqd))
108  for app in installed_data['apps']:
109  for areqd in ['app']:
110  if not areqd in app:
111  raise InvalidAppException("installed file [%s] app definition is missing required key [%s]"%(self.filename, areqd))
112  try:
113  available_apps.append(load_AppDefinition_by_name(app['app']))
114  except NotFoundException as e:
115  rospy.logerr(e)
116  continue
117  except Exception as e:
118  raise e
119 
120  self.available_apps = available_apps
121 
122  def update(self):
123  """
124  Update app list
125  """
126  s = os.stat(self.filename)
127  if s.st_mtime != self._file_mtime:
128  self._load()
129  self._file_mtime = s.st_mtime
130 
131  def get_available_apps(self, platform=None):
132  if platform is not None:
133  available_apps = filter(
134  lambda app: app.platform in [platform, 'all'],
135  self.available_apps)
136  return available_apps
137  else:
138  return self.available_apps
139 
140  def __eq__(self, other):
141  return self.filename == other.filename
142 
143  def __neq__(self, other):
144  return not self.__eq__(other)
145 
146 
147 class AppList(object):
148  def __init__(self, applist_directories, platform=None):
149  self.applist_directories = applist_directories
150  self.installed_files = {}
152  self.app_list = []
153  self.platform = platform
154 
156  self.need_update = True
157 
159  installed_files = []
160  for d in self.applist_directories:
161  for f in os.listdir(d):
162  if f.endswith(".installed"):
163  full_path = os.path.abspath(os.path.join(d, f))
164  installed_files.append(full_path)
165  return installed_files
166 
167  def _load(self, files):
168  if files:
169  installed_files = files
170  else:
171  installed_files = self.installed_files.keys()
172  invalid_installed_files = []
173  app_list = []
174  for f in installed_files:
175  try:
176  if f in self.installed_files:
177  # update InstalledFile object
178  installed_file = self.installed_files[f]
179  else:
180  # new installed file
181  installed_file = InstalledFile(f)
182  self.installed_files[f] = installed_file
183  installed_file.update()
184  app_list.extend(installed_file.get_available_apps(platform=self.platform))
185  rospy.loginfo("%d apps found in %s" % (len(installed_file.available_apps), installed_file.filename))
186  except AppException as e:
187  rospy.logerr("ERROR: %s" % (str(e)))
188  invalid_installed_files.append((f, e))
189  except Exception as e:
190  rospy.logerr("ERROR: %s" % (str(e)))
191  invalid_installed_files.append((f, e))
192 
193  self.app_list = app_list
194  self.invalid_installed_files = invalid_installed_files
195 
196  def get_app_list(self):
197  if not self.app_list:
198  self.update()
199  return [AppDefinition_to_App(ad) for ad in self.app_list]
200 
201  def add_directory(self, directory):
202  if not os.path.exists(directory):
203  raise IOError("applist directory %s does not exist." % directory)
204  if directory in self.applist_directory:
205  raise RuntimeError("applist directory %s already exists" % directory)
206  self.applist_directories.append(directory)
207  self.need_update = True
208 
209  def remove_directory(self, directory):
210  if directory not in self.applist_directory:
211  raise RuntimeError("applist directory %s does not in list" % directory)
212  self.applist_directory.remove(directory)
213  self.need_update = True
214 
215  def update(self):
216  """
217  Update app list
218  """
219  files = None
220  if self.need_update:
221  files = self._find_installed_files()
222  self.need_update = False
223  self._load(files)
def __init__(self, applist_directories, platform=None)
Definition: app_list.py:148
def add_directory(self, directory)
Definition: app_list.py:201
def _load(self, files)
Definition: app_list.py:167
def AppDefinition_to_App(app_definition)
Definition: app_list.py:78
def remove_directory(self, directory)
Definition: app_list.py:209
def read_Icon_file(filename)
Definition: app_list.py:63
def get_default_applist_directory()
Definition: app_list.py:51
def dict_to_KeyValue(d)
Definition: app_list.py:57
def load_AppDefinition_by_name(appname)
Definition: app.py:302
def __init__(self, filename)
Definition: app_list.py:93
def get_available_apps(self, platform=None)
Definition: app_list.py:131


app_manager
Author(s): Jeremy Leibs, Ken Conley, Yuki Furuta
autogenerated on Fri Mar 5 2021 03:07:47