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 .msg import App, ClientApp, KeyValue, Icon
00048 from .exceptions import AppException, InvalidAppException
00049 
00050 def get_default_applist_directory():
00051     """
00052     Default directory where applist configuration is stored.
00053     """
00054     return "/etc/robot/apps"
00055 
00056 def dict_to_KeyValue(d):
00057     l = []
00058     for k, v in d.iteritems():
00059         l.append(KeyValue(k, str(v)))
00060     return l
00061         
00062 def read_Icon_file(filename):
00063     icon = Icon()
00064     if filename == None or filename == "":
00065         return icon
00066     basename, extension = os.path.splitext(filename)
00067     if extension.lower() == ".jpg" or extension.lower() == ".jpeg":
00068         icon.format = "jpeg"
00069     elif extension.lower() == ".png":
00070         icon.format = "png"
00071     else:
00072         icon.format = ""
00073         return icon
00074     icon.data = open(filename, "rb").read()
00075     return icon
00076 
00077 def AppDefinition_to_App(app_definition):
00078     a = App(name=app_definition.name, display_name=app_definition.display_name, icon=read_Icon_file(app_definition.icon))
00079     a.client_apps = []
00080     for c in app_definition.clients:
00081         a.client_apps.append(ClientApp(c.client_type,
00082                                        dict_to_KeyValue(c.manager_data),
00083                                        dict_to_KeyValue(c.app_data)))
00084     return a
00085 
00086 class InstalledFile(object):
00087     """
00088     Models data stored in a .installed file.  These files are used to
00089     track installation of apps.
00090     """
00091     
00092     def __init__(self, filename):
00093         self.filename = filename
00094         # list of App
00095         self.available_apps = []
00096 
00097         self._file_mtime = None
00098         self.update()
00099 
00100     def _load(self):
00101         available_apps = []
00102         with open(self.filename) as f:
00103             installed_data = yaml.load(f)
00104             for reqd in ['apps']:
00105                 if not reqd in installed_data:
00106                     raise InvalidAppException("installed file [%s] is missing required key [%s]"%(self.filename, reqd))
00107             for app in installed_data['apps']:
00108                 for areqd in ['app']:
00109                     if not areqd in app:
00110                         raise InvalidAppException("installed file [%s] app definition is missing required key [%s]"%(self.filename, areqd))
00111                 available_apps.append(load_AppDefinition_by_name(app['app']))
00112                 
00113         self.available_apps = available_apps
00114 
00115     def update(self):
00116         """
00117         Update app list
00118         """
00119         s = os.stat(self.filename)
00120         if s.st_mtime != self._file_mtime:
00121             self._load()
00122             self._file_mtime = s.st_mtime
00123     
00124 class AppList(object):
00125     
00126     def __init__(self, applist_directories):
00127         self.applist_directories = applist_directories
00128         self.installed_files = {}
00129         self.invalid_installed_files = []
00130         self.app_list = []
00131         
00132         self._applist_directory_mtime = None
00133         self.update()
00134         
00135     def _load(self):
00136         app_list = []
00137         invalid_installed_files = []
00138         
00139         dir_list = [] 
00140         for i in self.applist_directories:
00141             for k in os.listdir(i):
00142                 dir_list.append(k)
00143             
00144         
00145         for f in set(self.installed_files.keys()) - set(dir_list):
00146             print "deleting installation data for [%s]"%(f)
00147             del self.installed_files[f]
00148         
00149         for i in self.applist_directories:
00150             for f in os.listdir(i):
00151                 print f
00152                 if not f.endswith('.installed'):
00153                     continue
00154                 try:
00155                     if f in self.installed_files:
00156                         installed_file = self.installed_files[f]
00157                         installed_file.update()
00158                     else:
00159                         print "loading installation data for [%s]"%(f)
00160                         filename = os.path.join(i, f)
00161                         installed_file = InstalledFile(filename)
00162                         self.installed_files[f] = installed_file
00163                     
00164                     app_list.extend(installed_file.available_apps)
00165 
00166                 except AppException as ae:
00167                     print >> sys.stderr, "ERROR: %s"%(str(ae))
00168                     invalid_installed_files.append((filename, ae))
00169                 except Exception as e:
00170                     print >> sys.stderr, "ERROR: %s"%(str(e))
00171                     invalid_installed_files.append((filename, e))
00172 
00173         self.app_list = app_list
00174         self.invalid_installed_files = invalid_installed_files
00175         
00176     def get_app_list(self):
00177         return [AppDefinition_to_App(ad) for ad in self.app_list]
00178     
00179     def add_directory(self, directory):
00180         self.applist_directories.append(directory)
00181 
00182     def update(self):
00183         """
00184         Update app list
00185         """
00186         
00187         bad = True
00188         #TODO: this detects when the directories are actually modified.
00189         #It does not work because os.stat(i).st_mtime does not change if
00190         #only a file is modified.
00191         #s = []
00192         #for i in self.applist_directories:
00193         #    s.append(os.stat(i).st_mtime)
00194         #
00195         #bad = True
00196         #if self._applist_directory_mtime != None:
00197         #    if len(s) == len(self._applist_directory_mtime):
00198         #        bad = False
00199         #        for i in range(0, len(s)):
00200         #            if s[i] != self._applist_directory_mtime[i]:
00201         #                bad = True
00202         
00203         if (bad):
00204             self._load()
00205             #self._applist_directory_mtime = s


app_manager
Author(s): Jeremy Leibs, Ken Conley
autogenerated on Mon Dec 2 2013 11:36:52