app.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: app.py 14667 2011-08-12 23:55:04Z pratkanis $
34 
35 # author: leibs, kwc
36 
37 import os
38 import errno
39 import yaml
40 
41 import roslib.names
42 from rospkg import ResourceNotFound
43 from .exceptions import AppException, InvalidAppException, NotFoundException, InternalAppException
44 
45 class Interface(object):
46  def __init__(self, subscribed_topics, published_topics):
47  self.subscribed_topics = subscribed_topics
48  self.published_topics = published_topics
49 
50  def __eq__(self, other):
51  if not isinstance(other, Interface):
52  return False
53  return self.subscribed_topics == other.subscribed_topics and \
54  self.published_topics == other.published_topics
55 
56 class Client(object):
57  __slots__ = ['client_type', 'manager_data', 'app_data']
58  def __init__(self, client_type, manager_data, app_data):
59  self.client_type = client_type
60  self.manager_data = manager_data
61  self.app_data = app_data
62 
63  def as_dict(self):
64  return {'client_type': self.client_type, 'manager_data': self.manager_data, 'app_data': self.app_data}
65 
66  def __eq__(self, other):
67  if not isinstance(other, Client):
68  return False
69  return self.client_type == other.client_type and \
70  self.manager_data == other.manager_data and \
71  self.app_data == other.app_data
72 
73  def __repr__(self):
74  return yaml.dump(self.as_dict())
75 
76 class AppDefinition(object):
77  __slots__ = ['name', 'display_name', 'description', 'platform',
78  'launch', 'interface', 'clients', 'icon', 'plugins', 'plugin_order',
79  'timeout']
80  def __init__(self, name, display_name, description, platform,
81  launch, interface, clients, icon=None, plugins=None, plugin_order=None,
82  timeout=None):
83  self.name = name
84  self.display_name = display_name
85  self.description = description
86  self.platform=platform
87  self.launch = launch
88  self.interface = interface
89  self.clients = clients
90  self.icon = icon
91  self.plugins = plugins
92  self.plugin_order = plugin_order
93  self.timeout = timeout
94 
95  def __repr__(self):
96  d = {}
97  for s in self.__slots__:
98  if s == 'clients':
99  d[s] = [c.as_dict() for c in self.clients]
100  else:
101  d[s] = getattr(self, s)
102  return yaml.dump(d)
103  # return "name: %s\ndisplay: %s\ndescription: %s\nplatform: %s\nlaunch: %s\ninterface: %s\nclients: %s"%(self.name, self.display_name, self.description, self.platform, self.launch, self.interface, self.clients)
104 
105  def __eq__(self, other):
106  if not isinstance(other, AppDefinition):
107  return False
108  return self.name == other.name and \
109  self.display_name == other.display_name and \
110  self.description == other.description and \
111  self.platform == other.platform and \
112  self.launch == other.launch and \
113  self.interface == other.interface and \
114  self.clients == other.clients and \
115  self.icon == other.icon
116 
117 def find_resource(resource):
118  """
119  @return: filepath of resource. Does not validate if filepath actually exists.
120 
121  @raise ValueError: if resource is not a valid resource name.
122  @raise rospkg.ResourceNotFound: if package referred
123  to in resource name cannot be found.
124  @raise NotFoundException: if resource does not exist.
125  """
126  p, a = roslib.names.package_resource_name(resource)
127  if not p:
128  raise ValueError("Resource is missing package name: %s"%(resource))
129  matches = roslib.packages.find_resource(p, a)
130  # TODO: convert ValueError to better type for better error messages
131  if len(matches) == 1:
132  return matches[0]
133  elif not matches:
134  raise NotFoundException("No resource [%s]"%(resource))
135  else:
136  raise ValueError("Multiple resources named [%s]"%(resource))
137 
139  """
140  @raise IOError: I/O error reading file (e.g. does not exist)
141  @raise InvalidAppException: if app file is invalid
142  """
143  with open(filename,'r') as f:
144  y = yaml.load(f.read())
145  y = y or {} #coerce to dict
146  try:
147  subscribed_topics = y.get('subscribed_topics', {})
148  published_topics = y.get('published_topics', {})
149  except KeyError:
150  raise InvalidAppException("Malformed interface, missing keys")
151  return Interface(published_topics=published_topics, subscribed_topics=subscribed_topics)
152 
153 def _AppDefinition_load_icon_entry(app_data, appfile="UNKNOWN"):
154  """
155  @raise InvalidAppExcetion: if app definition is invalid.
156  """
157  # load/validate launch entry
158  try:
159  icon_resource = app_data.get('icon', '')
160  if icon_resource == '':
161  return None
162  icon_filename = find_resource(icon_resource)
163  if not icon_filename or not os.path.exists(icon_filename):
164  return None
165  return icon_filename
166  except ValueError as e:
167  raise InvalidAppException("Malformed appfile [%s]: bad icon entry: %s"%(appfile, e))
168  except NotFoundException:
169  # TODO: make this a soft fail?
170  raise InvalidAppException("App file [%s] refers to icon that cannot be found"%(appfile))
171  except ResourceNotFound as e:
172  raise InvalidAppException("App file [%s] refers to package that is not installed: %s"%(appfile, str(e)))
173 
174 def _AppDefinition_load_launch_entry(app_data, appfile="UNKNOWN"):
175  """
176  @raise InvalidAppExcetion: if app definition is invalid.
177  """
178  # load/validate launch entry
179  try:
180  launch = find_resource(app_data['launch'])
181  if not os.path.exists(launch):
182  raise InvalidAppException("Malformed appfile [%s]: refers to launch that does not exist."%(appfile))
183  return launch
184  except ValueError as e:
185  raise InvalidAppException("Malformed appfile [%s]: bad launch entry: %s"%(appfile, e))
186  except NotFoundException:
187  raise InvalidAppException("App file [%s] refers to launch that is not installed"%(appfile))
188  except ResourceNotFound as e:
189  raise InvalidAppException("App file [%s] refers to package that is not installed: %s"%(appfile, str(e)))
190 
191 def _AppDefinition_load_interface_entry(app_data, appfile="UNKNOWN"):
192  """
193  @raise InvalidAppExcetion: if app definition is invalid.
194  """
195  # load/validate interface entry
196  try:
197  return load_Interface_from_file(find_resource(app_data['interface']))
198  except IOError as e:
199  if e.errno == errno.ENOENT:
200  raise InvalidAppException("Malformed appfile [%s]: refers to interface file that does not exist"%(appfile))
201  else:
202  raise InvalidAppException("Error with appfile [%s]: cannot read interface file"%(appfile))
203  except ValueError:
204  raise InvalidAppException("Malformed appfile [%s]: bad interface entry"%(appfile))
205  except ResourceNotFound as e:
206  raise InvalidAppException("App file [%s] refers to package that is not installed: %s"%(appfile, str(e)))
207 
208 def _AppDefinition_load_clients_entry(app_data, appfile="UNKNOWN"):
209  """
210  @raise InvalidAppExcetion: if app definition is invalid.
211  """
212  clients_data = app_data.get('clients', [])
213  clients = []
214  for c in clients_data:
215  for reqd in ['type', 'manager']:
216  if not reqd in c:
217  raise InvalidAppException("Malformed appfile [%s], missing required key [%s]"%(appfile, reqd))
218  client_type = c['type']
219  manager_data = c['manager']
220  if not type(manager_data) == dict:
221  raise InvalidAppException("Malformed appfile [%s]: manager data must be a map"%(appfile))
222 
223  app_data = c.get('app', {})
224  if not type(app_data) == dict:
225  raise InvalidAppException("Malformed appfile [%s]: app data must be a map"%(appfile))
226 
227  clients.append(Client(client_type, manager_data, app_data))
228  return clients
229 
230 
231 def _AppDefinition_load_plugins_entry(app_data, appfile="UNKNOWN"):
232  """
233  @raise InvalidAppException: if app definition is invalid.
234  """
235  # load/validate launch entry
236  try:
237  plugins = app_data.get('plugins', '')
238  if plugins == '':
239  return None
240  return plugins
241  except ValueError as e:
242  raise InvalidAppException("Malformed appfile [%s]: bad plugins entry: %s"%(appfile, e))
243 
244 
245 def _AppDefinition_load_plugin_order_entry(app_data, appfile="UNKNOWN"):
246  """
247  @raise InvalidAppException: if app definition is invalid.
248  """
249  # load/validate launch entry
250  try:
251  plugin_order = app_data.get('plugin_order', '')
252  if plugin_order == '':
253  return None
254  return plugin_order
255  except ValueError as e:
256  raise InvalidAppException("Malformed appfile [%s]: bad plugin_order entry: %s"%(appfile, e))
257 
258 
259 def _AppDefinition_load_timeout_entry(app_data, appfile="UNKNOWN"):
260  """
261  @raise InvalidAppException: if app definition is invalid.
262  """
263  # load/validate launch entry
264  try:
265  timeout = app_data.get('timeout', '')
266  if timeout == '':
267  return None
268  return timeout
269  except ValueError as e:
270  raise InvalidAppException("Malformed appfile [%s]: bad timeout entry: %s"%(appfile, e))
271 
272 
273 
274 def load_AppDefinition_from_file(appfile, appname):
275  """
276  @raise InvalidAppExcetion: if app definition is invalid.
277  @raise IOError: I/O error reading appfile (e.g. file does not exist).
278  """
279  with open(appfile,'r') as f:
280  app_data = yaml.load(f.read())
281  for reqd in ['launch', 'interface', 'platform']:
282  if not reqd in app_data:
283  raise InvalidAppException("Malformed appfile [%s], missing required key [%s]"%(appfile, reqd))
284 
285  display_name = app_data.get('display', appname)
286  description = app_data.get('description', '')
287  platform = app_data['platform']
288 
289 
290  launch = _AppDefinition_load_launch_entry(app_data, appfile)
291  interface = _AppDefinition_load_interface_entry(app_data, appfile)
292  clients = _AppDefinition_load_clients_entry(app_data, appfile)
293  icon = _AppDefinition_load_icon_entry(app_data, appfile)
294  plugins = _AppDefinition_load_plugins_entry(app_data, appfile)
295  plugin_order = _AppDefinition_load_plugin_order_entry(app_data, appfile)
296  timeout = _AppDefinition_load_timeout_entry(app_data, appfile)
297 
298  return AppDefinition(appname, display_name, description, platform,
299  launch, interface, clients, icon,
300  plugins, plugin_order, timeout)
301 
303  """
304  @raise InvalidAppExcetion: if app definition is invalid.
305  @raise NotFoundExcetion: if app definition is not installed.
306  @raise ValueError: if appname is invalid.
307  """
308  if not appname:
309  raise ValueError("app name is empty")
310 
311  try:
312  appfile = find_resource(appname + '.app')
313  except ResourceNotFound as e:
314  raise NotFoundException("Cannot locate app file for %s: package is not installed."%(appname))
315 
316  try:
317  return load_AppDefinition_from_file(appfile, appname)
318  except IOError as e:
319  if e.errno == errno.ENOENT:
320  raise NotFoundException("Cannot locate app file for %s."%(appname))
321  else:
322  raise InternalAppException("I/O error loading AppDefinition file: %s."%(e.errno))
def _AppDefinition_load_launch_entry(app_data, appfile="UNKNOWN")
Definition: app.py:174
def load_AppDefinition_from_file(appfile, appname)
Definition: app.py:274
def find_resource(resource)
Definition: app.py:117
def as_dict(self)
Definition: app.py:63
def __eq__(self, other)
Definition: app.py:105
def __init__(self, name, display_name, description, platform, launch, interface, clients, icon=None, plugins=None, plugin_order=None, timeout=None)
Definition: app.py:82
def __init__(self, subscribed_topics, published_topics)
Definition: app.py:46
def _AppDefinition_load_interface_entry(app_data, appfile="UNKNOWN")
Definition: app.py:191
def _AppDefinition_load_icon_entry(app_data, appfile="UNKNOWN")
Definition: app.py:153
def __eq__(self, other)
Definition: app.py:50
def _AppDefinition_load_clients_entry(app_data, appfile="UNKNOWN")
Definition: app.py:208
def __repr__(self)
Definition: app.py:73
def __init__(self, client_type, manager_data, app_data)
Definition: app.py:58
def load_AppDefinition_by_name(appname)
Definition: app.py:302
def load_Interface_from_file(filename)
Definition: app.py:138
def _AppDefinition_load_plugin_order_entry(app_data, appfile="UNKNOWN")
Definition: app.py:245
def __eq__(self, other)
Definition: app.py:66
def _AppDefinition_load_timeout_entry(app_data, appfile="UNKNOWN")
Definition: app.py:259
def _AppDefinition_load_plugins_entry(app_data, appfile="UNKNOWN")
Definition: app.py:231


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