00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 import string
00019 import sys,os
00020 import glob
00021
00022 import OpenRTM_aist
00023
00024
00025 CONFIG_EXT = "manager.modules.config_ext"
00026 CONFIG_PATH = "manager.modules.config_path"
00027 DETECT_MOD = "manager.modules.detect_loadable"
00028 MOD_LOADPTH = "manager.modules.load_path"
00029 INITFUNC_SFX = "manager.modules.init_func_suffix"
00030 INITFUNC_PFX = "manager.modules.init_func_prefix"
00031 ALLOW_ABSPATH = "manager.modules.abs_path_allowed"
00032 ALLOW_URL = "manager.modules.download_allowed"
00033 MOD_DWNDIR = "manager.modules.download_dir"
00034 MOD_DELMOD = "manager.modules.download_cleanup"
00035 MOD_PRELOAD = "manager.modules.preload"
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 class ModuleManager:
00055 """
00056 """
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 def __init__(self, prop):
00077 self._properties = prop
00078
00079 self._configPath = prop.getProperty(CONFIG_PATH).split(",")
00080 for i in range(len(self._configPath)):
00081 tmp = [self._configPath[i]]
00082 OpenRTM_aist.eraseHeadBlank(tmp)
00083 self._configPath[i] = tmp[0]
00084 self._loadPath = prop.getProperty(MOD_LOADPTH,"./").split(",")
00085 for i in range(len(self._loadPath)):
00086 tmp = [self._loadPath[i]]
00087 OpenRTM_aist.eraseHeadBlank(tmp)
00088 self._loadPath[i] = tmp[0]
00089
00090 self._absoluteAllowed = OpenRTM_aist.toBool(prop.getProperty(ALLOW_ABSPATH),
00091 "yes", "no", False)
00092
00093 self._downloadAllowed = OpenRTM_aist.toBool(prop.getProperty(ALLOW_URL),
00094 "yes", "no", False)
00095
00096 self._initFuncSuffix = prop.getProperty(INITFUNC_SFX)
00097 self._initFuncPrefix = prop.getProperty(INITFUNC_PFX)
00098 self._modules = OpenRTM_aist.ObjectManager(self.DLLPred)
00099 self._rtcout = None
00100 self._mgr = OpenRTM_aist.Manager.instance()
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 def __del__(self):
00115 self.unloadAll()
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 class Error:
00126 def __init__(self, reason_):
00127 self.reason = reason_
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 class NotFound:
00139 def __init__(self, name_):
00140 self.name = name_
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 class FileNotFound(NotFound):
00152 def __init__(self, name_):
00153 ModuleManager.NotFound.__init__(self, name_)
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 class ModuleNotFound(NotFound):
00165 def __init__(self, name_):
00166 ModuleManager.NotFound.__init__(self, name_)
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 class SymbolNotFound(NotFound):
00178 def __init__(self, name_):
00179 ModuleManager.NotFound.__init__(self, name_)
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 class NotAllowedOperation(Error):
00191 def __init__(self, reason_):
00192 ModuleManager.Error.__init__(self, reason_)
00193 ModuleManager.Error.__init__(self, reason_)
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204 class InvalidArguments(Error):
00205 def __init__(self, reason_):
00206 ModuleManager.Error.__init__(self, reason_)
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 class InvalidOperation(Error):
00218 def __init__(self, reason_):
00219 ModuleManager.Error.__init__(self, reason_)
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 def load(self, file_name, init_func=None):
00246 if not self._rtcout:
00247 self._rtcout = self._mgr.getLogbuf("ModuleManager")
00248
00249 self._rtcout.RTC_TRACE("load(fname = %s)", file_name)
00250 if file_name == "":
00251 raise ModuleManager.InvalidArguments, "Invalid file name."
00252
00253 if OpenRTM_aist.isURL(file_name):
00254 if not self._downloadAllowed:
00255 raise ModuleManager.NotAllowedOperation, "Downloading module is not allowed."
00256 else:
00257 raise ModuleManager.NotFound, "Not implemented."
00258
00259 import_name = os.path.split(file_name)[-1]
00260 pathChanged=False
00261 file_path = None
00262 if OpenRTM_aist.isAbsolutePath(file_name):
00263 if not self._absoluteAllowed:
00264 raise ModuleManager.NotAllowedOperation, "Absolute path is not allowed"
00265 else:
00266 splitted_name = os.path.split(file_name)
00267 save_path = sys.path[:]
00268 sys.path.append(splitted_name[0])
00269 pathChanged = True
00270 import_name = splitted_name[-1]
00271 file_path = file_name
00272
00273 else:
00274 file_path = self.findFile(file_name, self._loadPath)
00275 if not file_path:
00276 raise ModuleManager.InvalidArguments, "Invalid file name."
00277
00278 if not self.fileExist(file_path):
00279 raise ModuleManager.FileNotFound, file_name
00280
00281 if not pathChanged:
00282 splitted_name = os.path.split(file_path)
00283 sys.path.append(splitted_name[0])
00284
00285 ext_pos = import_name.find(".py")
00286 if ext_pos > 0:
00287 import_name = import_name[:ext_pos]
00288 mo = __import__(str(import_name))
00289
00290 if pathChanged:
00291 sys.path = save_path
00292
00293 dll = self.DLLEntity(mo,OpenRTM_aist.Properties())
00294 dll.properties.setProperty("file_path",file_path)
00295 self._modules.registerObject(dll)
00296
00297
00298 if init_func is None:
00299 return file_name
00300
00301 self.symbol(file_path,init_func)(self._mgr)
00302
00303 return file_name
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 def unload(self, file_name):
00319 dll = self._modules.find(file_name)
00320 if not dll:
00321 raise ModuleManager.NotFound, file_name
00322
00323 self._modules.unregisterObject(file_name)
00324 return
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 def unloadAll(self):
00339 dlls = self._modules.getObjects()
00340
00341 for dll in dlls:
00342 ident = dll.properties.getProperty("file_path")
00343 self._modules.unregisterObject(ident)
00344 return
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 def symbol(self, file_name, func_name):
00361 dll = self._modules.find(file_name)
00362 if not dll:
00363 raise ModuleManager.ModuleNotFound, file_name
00364
00365 func = getattr(dll.dll,func_name,None)
00366
00367 if not func:
00368 raise ModuleManager.SymbolNotFound, func_name
00369
00370 return func
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 def setLoadpath(self, load_path_list):
00386 self._loadPath = load_path_list
00387 return
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 def getLoadPath(self):
00404 return self._loadPath
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 def addLoadpath(self, load_path):
00420 for path in load_path:
00421 self._loadPath.append(path)
00422 return
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 def getLoadedModules(self):
00440 dlls = self._modules.getObjects()
00441 modules = []
00442 for dll in dlls:
00443 modules.append(dll.properties)
00444
00445 return modules
00446
00447
00448 def __getRtcProfile(self, fname):
00449
00450 fullname = fname
00451
00452 dirname = os.path.dirname(fname)
00453 sys.path.append(dirname)
00454
00455 basename = os.path.basename(fname)
00456
00457 classname = basename.split(".")[0].lower()
00458
00459
00460
00461 oldp = self._mgr.getFactoryProfiles()
00462
00463
00464 comp_spec_name = classname+"_spec"
00465
00466 try:
00467 imp_file = __import__(basename.split(".")[0])
00468 except:
00469 return None
00470 comp_spec = getattr(imp_file,comp_spec_name,None)
00471 if not comp_spec:
00472 return None
00473 newp = OpenRTM_aist.Properties(defaults_str=comp_spec)
00474
00475 profs = []
00476
00477 exists = False
00478 for i in range(len(oldp)):
00479 if oldp[i].getProperty("implementation_id") == newp.getProperty("implementation_id") and \
00480 oldp[i].getProperty("type_name") == newp.getProperty("type_name") and \
00481 oldp[i].getProperty("description") == newp.getProperty("description") and \
00482 oldp[i].getProperty("version") == newp.getProperty("version"):
00483 exists = True
00484 if not exists:
00485 profs.append(newp)
00486
00487
00488
00489 if len(profs) == 0:
00490 return OpenRTM_aist.Properties()
00491
00492 if len(profs) > 1:
00493 return None
00494
00495 return profs[0]
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 def getLoadableModules(self):
00512
00513 modules_ = []
00514 for path in self._loadPath:
00515 if path == "":
00516 continue
00517
00518 flist = glob.glob(path + os.sep + '*.py')
00519 for file in flist:
00520 if file.find("__init__.py") == -1:
00521 modules_.append(file)
00522
00523 props = []
00524
00525 for mod_ in modules_:
00526 prop = self.__getRtcProfile(mod_)
00527 if prop:
00528 prop.setProperty("module_file_name",os.path.basename(mod_))
00529 prop.setProperty("module_file_path", mod_)
00530 props.append(prop)
00531
00532 return props
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 def allowAbsolutePath(self):
00548 self._absoluteAllowed = True
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562 def disallowAbsolutePath(self):
00563 self._absoluteAllowed = False
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 def allowModuleDownload(self):
00580 self._downloadAllowed = True
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594 def disallowModuleDownload(self):
00595 self._downloadAllowed = False
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 def findFile(self, fname, load_path):
00614 file_name = fname
00615 for path in load_path:
00616 if fname.find(".py") == -1:
00617 f = str(path) + os.sep + str(file_name)+".py"
00618 else:
00619 f = str(path)+ os.sep + str(file_name)
00620 if self.fileExist(f):
00621 return f
00622 return ""
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 def fileExist(self, filename):
00640 fname = filename
00641 if fname.find(".py") == -1:
00642 fname = str(filename)+".py"
00643
00644 if os.path.isfile(fname):
00645 return True
00646
00647 return False
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665 def getInitFuncName(self, file_path):
00666 base_name = os.path.basename(file_path)
00667 return str(self._initFuncPrefix)+str(base_name)+str(self._initFuncSuffix)
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 class DLL:
00679 def __init__(self, dll):
00680 self.dll = dll
00681 return
00682
00683
00684 class DLLEntity:
00685 def __init__(self,dll,prop):
00686 self.dll = dll
00687 self.properties = prop
00688
00689
00690 class DLLPred:
00691 def __init__(self, name=None, factory=None):
00692 self._filepath = name or factory
00693
00694 def __call__(self, dll):
00695 return self._filepath == dll.properties.getProperty("file_path")