Package Task :: Package Tools :: Module System
[hide private]
[frames] | no frames]

Source Code for Module Task.Tools.System

   1  ''' 
   2  Defines L{Tools} for registering, unregistering, introspecting, and otherwise 
   3  manging L{Tier}s, L{Perk}s, and L{Task}s. 
   4   
   5  @author: Peter Parente 
   6  @author: Scott Haeger 
   7  @organization: IBM Corporation 
   8  @copyright: Copyright (c) 2005, 2007 IBM Corporation 
   9  @license: The BSD License 
  10   
  11  All rights reserved. This program and the accompanying materials are made  
  12  available under the terms of the BSD license which accompanies 
  13  this distribution, and is available at 
  14  U{http://www.opensource.org/licenses/bsd-license.php} 
  15  ''' 
  16  import weakref, sys 
  17  from Error import * 
  18  import AEEvent 
  19  import Base 
  20  import AEConstants, UIRegistrar 
  21   
22 -class System(Base.TaskTools):
23 ''' 24 Provides methods for managing L{Tier}s, L{Perk}s, and L{Task}s. 25 '''
26 - def getProfileName(self):
27 ''' 28 Gets the name of the profile LSR is running under. 29 30 @return: Profile name 31 @rtype: string 32 ''' 33 return self.acc_eng.getProfile()
34
35 - def pushPerk(self, *names):
36 ''' 37 Adds one or more L{Perk}s to the top of the stack. If more than one L{Perk} 38 is specified, the last specified L{Perk} will be at the top of the stack 39 when this method completes. That is, the behavior of pushing more than one 40 L{Perk} at a time is the same as if each L{Perk} were pushed individually. 41 42 @param names: Names of L{Perk}s to add 43 @type names: string 44 ''' 45 reg = UIRegistrar 46 perks = [] 47 for name in names: 48 perk = reg.loadOne(name) 49 if perk is not None: 50 perks.append(perk) 51 self.tier.pushPerk(self.acc_eng, *perks)
52
53 - def insertPerk(self, index, perk):
54 ''' 55 Adds one L{Perk} to the stack at the insertion index. Negative indices are 56 valid per Python list convention. 57 58 @param index: Index at which the L{Perk} should be inserted into the stack 59 where zero is the bottom 60 @type index: integer 61 @param perk: L{Perk} to add 62 @type perk: L{Perk} 63 ''' 64 reg = UIRegistrar 65 perk = reg.loadOne(perk) 66 if perk is not None: 67 self.tier.insertPerk(self.acc_eng, index, perk)
68
69 - def popPerk(self, *indices):
70 ''' 71 Removes one or more L{Perk}s from the stack given their indices. 72 73 @param indices: Indices of L{Perk}s to remove 74 @type indices: list of integer 75 @raise IndexError: When the stack is empty 76 @raise ValueError: When specified L{Perk} is not found 77 ''' 78 self.tier.popPerk(*indices)
79
80 - def popThisPerk(self):
81 ''' 82 Removes the current L{Perk} from the L{Tier}. No L{Task.Tools} methods 83 should be invoked after this call. 84 ''' 85 perks = self.tier.getPerks() 86 i = perks.index(self.perk) 87 self.tier.popPerk(i)
88
89 - def reloadPerks(self):
90 ''' 91 Reloads all L{Perk}s in the current L{Tier}. Any changes made to the 92 L{Perk} logic will take effect immediately after the reload. This method 93 does not refer to the L{Perk}s associated with the current profile. It 94 simply reloads all currently loaded L{Perk}s. 95 ''' 96 reg = UIRegistrar 97 # get official registered Perk names for all existing Perks in this Tier 98 names = self.getPerkClassNames() 99 names.reverse() 100 # store Tier and AccessEngine references before deletion 101 tier = self.tier 102 acc_eng = self.acc_eng 103 # clear out existing Perks 104 self.tier.clearPerks() 105 # restore the Tier reference 106 self.tier = tier 107 self.acc_eng = acc_eng 108 # push all new Perks 109 self.pushPerk(*names) 110 # throw the refs away permanently 111 self.tier = None 112 self.acc_eng = None
113
114 - def _getUIEInstances(self, kind, which):
115 ''' 116 Internal method for getting instances of all installed or associated 117 L{UIElement}s for the given kind. 118 119 @note: Installed UIEs that are not importable because of missing 120 dependencies or other errors are not included in the list. 121 @note: Getting loaded chooser names is not currently supported. 122 @param kind: Kind of L{UIElement} to fetch metadata for, one of 123 L{UIRegistrar.ALL_KINDS} 124 @type kind: string 125 @param which: Which names to get, one of the UIE_ constants in 126 L{AEConstants} 127 @type which: integer 128 @return: All descriptions 129 @rtype: list of string 130 ''' 131 reg = UIRegistrar 132 if which == AEConstants.UIE_LOADED: 133 # handle each type serparately, as loaded instances are stored in diverse 134 # locations in LSR 135 if kind == reg.PERK: 136 # get Perks in this Tier 137 uies = self.tier.getPerks() 138 elif kind == reg.DEVICE: 139 # get devices 140 uies = self.device_man.getDevices() 141 elif kind == reg.CHOOSER: 142 # not supported at present 143 uies = [] 144 elif kind == reg.MONITOR: 145 imons, omons = self.device_man.getMonitors() 146 uies = list(set(imons) + set(omons) + set(self.tier_man.getMonitors()) 147 + set(self.event_man.getMonitors())) 148 # we already have live instances here, so just return them 149 return uies 150 151 # use the UIRegistrar to look up class names 152 if which == AEConstants.UIE_INSTALLED: 153 names = reg.listInstalled(kind) 154 elif which == AEConstants.UIE_ALL_ASSOCIATED: 155 names = reg.listAssociated(kind, self.acc_eng.getProfile()) 156 elif which == AEConstants.UIE_TIER_ASSOCIATED and kind == reg.PERK: 157 names = reg.listAssociated(kind, self.acc_eng.getProfile(), 158 self.tier.getName()) 159 # here we need to contruct live instances because all we have is a class 160 # name from the UIRegistrar 161 l = [] 162 for name in names: 163 uie = reg.loadOne(name) 164 if uie is not None: 165 l.append(uie) 166 return l
167
168 - def _getClassNames(self, kind, which):
169 ''' 170 Internal method for getting class names of all installed or associated 171 L{UIElement}s for the given kind. 172 173 @note: Installed UIEs that are not importable because of missing 174 dependencies are not listed as installed to maintain parity with 175 L{_getNames} and L{_getDescriptions}. 176 @param kind: Kind of L{UIElement} to fetch metadata for, one of 177 L{UIRegistrar.ALL_KINDS} 178 @type kind: string 179 @param which: Which names to get, one of the UIE_ constants in 180 L{AEConstants} 181 @type which: integer 182 @return: All descriptions 183 @rtype: list of string 184 ''' 185 reg = UIRegistrar 186 if which == AEConstants.UIE_INSTALLED: 187 names = reg.listInstalled(kind) 188 elif which == AEConstants.UIE_ALL_ASSOCIATED: 189 names = reg.listAssociated(kind, self.acc_eng.getProfile()) 190 elif which == AEConstants.UIE_TIER_ASSOCIATED and kind == reg.PERK: 191 names = reg.listAssociated(kind, self.acc_eng.getProfile(), 192 self.tier.getName()) 193 # make sure the UIE is loadable before listing it 194 return filter(lambda x: reg.loadOne(x) is not None, names)
195
196 - def _getNames(self, kind, which):
197 ''' 198 Internal method for getting names of all installed or associated 199 L{UIElement}s for the given kind. 200 201 @param kind: Kind of L{UIElement} to fetch metadata for, one of 202 L{UIRegistrar.ALL_KINDS} 203 @type kind: string 204 @param which: Which names to get, one of the UIE_ constants in 205 L{AEConstants} 206 @type which: integer 207 @return: All descriptions 208 @rtype: list of string 209 ''' 210 reg = UIRegistrar 211 if which == AEConstants.UIE_INSTALLED: 212 return [uie.getName() for uie in (reg.loadOne(name) for name in 213 reg.listInstalled(kind)) 214 if uie is not None] 215 elif which in (AEConstants.UIE_ALL_ASSOCIATED, 216 AEConstants.UIE_TIER_ASSOCIATED): 217 names = self._getClassNames(kind, which) 218 if names is None: 219 return None 220 return [uie.getName() for uie in (reg.loadOne(name) for name in names) 221 if uie is not None]
222
223 - def _getDescriptions(self, kind, which):
224 ''' 225 Internal method for getting descriptions of all installed or associated 226 L{UIElement}s for the given kind. 227 228 @param kind: Kind of L{UIElement} to fetch metadata for, one of 229 L{UIRegistrar.ALL_KINDS} 230 @type kind: string 231 @param which: Which names to get, one of the UIE_ constants in 232 L{AEConstants} 233 @type which: integer 234 @return: All descriptions 235 @rtype: list of string 236 ''' 237 reg = UIRegistrar 238 if which == AEConstants.UIE_INSTALLED: 239 return [uie.getDescription() for uie in (reg.loadOne(name) for name in 240 reg.listInstalled(kind)) 241 if uie is not None] 242 elif which in (AEConstants.UIE_ALL_ASSOCIATED, 243 AEConstants.UIE_TIER_ASSOCIATED): 244 names = self._getClassNames(kind, which) 245 if names is None: 246 return None 247 return [uie.getDescription() for uie in (reg.loadOne(name) 248 for name in names) 249 if uie is not None]
250
251 - def getPerkMetadata(self, which=AEConstants.UIE_LOADED):
252 ''' 253 Gets metadata for all L{Perk}s in this L{Tier}, all installed L{Perk}s, 254 L{Perk}s associated with this L{Tier}, or all L{Perk}s associated with this 255 profile depending on the which flag. Includes L{Perk} class names, human 256 readable names, and descriptions. 257 258 The default value is used if which is invalid. 259 260 @param which: Which names to get, one of the UIE_ constants in 261 L{AEConstants} 262 @type which: integer 263 @return: Class names, names, descriptions 264 @rtype: list of 3-tuple of string 265 ''' 266 uies = self._getUIEInstances(UIRegistrar.PERK, which) 267 return zip((uie.getClassName() for uie in uies), 268 (uie.getName() for uie in uies), 269 (uie.getDescription() for uie in uies))
270
271 - def getDeviceMetadata(self, which=AEConstants.UIE_LOADED):
272 ''' 273 Gets metadata for all L{AEOutput} and L{AEInput} devices currently loaded 274 in, installed in, or associated with the active profile depending on the 275 which flag. 276 277 The default value is used if which is invalid. 278 279 @param which: Which names to get, one of the UIE_ constants in 280 L{AEConstants} 281 @type which: integer 282 @return: Class names, names, descriptions 283 @rtype: list of 3-tuple of string 284 ''' 285 uies = self._getUIEInstances(UIRegistrar.DEVICE, which) 286 return zip((uie.getClassName() for uie in uies), 287 (uie.getName() for uie in uies), 288 (uie.getDescription() for uie in uies))
289
290 - def getMonitorMetadata(self, which=AEConstants.UIE_LOADED):
291 ''' 292 Gets metadata for all L{AEMonitor}s currently loaded in, installed in, or 293 associated with the active profile depending on the which flag. 294 295 The default value is used if which is invalid. 296 297 @param which: Which names to get, one of the UIE_ constants in 298 L{AEConstants} 299 @type which: integer 300 @return: Class names, names, descriptions 301 @rtype: list of 3-tuple of string 302 ''' 303 uies = self._getUIEInstances(UIRegistrar.MONITOR, which) 304 return zip((uie.getClassName() for uie in uies), 305 (uie.getName() for uie in uies), 306 (uie.getDescription() for uie in uies))
307
309 ''' 310 Gets metadata for all L{AEChooser}s installed in or associated with the 311 active profile depending on the which flag. 312 313 The default value is used if which is invalid. 314 315 @note: Getting loaded chooser names is not currently supported. 316 @param which: Which names to get, one of the UIE_ constants in 317 L{AEConstants} 318 @type which: integer 319 @return: Class names, names, descriptions 320 @rtype: list of 3-tuple of string 321 ''' 322 uies = self._getUIEInstances(UIRegistrar.CHOOSER, which) 323 return zip((uie.getClassName() for uie in uies), 324 (uie.getName() for uie in uies), 325 (uie.getDescription() for uie in uies))
326
328 ''' 329 Gets the programmatic class names of all L{AEOutput} and L{AEInput} devices 330 currently loaded in, installed in, or associated with the active profile 331 depending on the which flag. 332 333 The default value is used if which is invalid. 334 335 @param which: Which names to get, one of the UIE_ constants in 336 L{AEConstants} 337 @type which: integer 338 @return: Names of all L{AEOutput} and L{AEInput} classes 339 @rtype: list of string 340 ''' 341 if which != AEConstants.UIE_LOADED: 342 return self._getClassNames(UIRegistrar.DEVICE, which) 343 else: 344 return [dev.getClassName() for dev in self.device_man.getDevices()]
345
346 - def getDeviceNames(self, which=AEConstants.UIE_LOADED):
347 ''' 348 Gets the human readable names of all L{AEOutput} and L{AEInput} devices 349 currently loaded in, installed in, or associated with the active profile 350 depending on the which flag. 351 352 The default value is used if which is invalid. 353 354 @param which: Which names to get, one of the UIE_ constants in 355 L{AEConstants} 356 @type which: integer 357 @return: Names of all L{AEOutput} and L{AEInput} devices 358 @rtype: list of string 359 ''' 360 if which != AEConstants.UIE_LOADED: 361 return self._getNames(UIRegistrar.DEVICE, which) 362 else: 363 return [dev.getName() for dev in self.device_man.getDevices()]
364
366 ''' 367 Gets the descriptions of all L{AEOutput} and L{AEInput} devices 368 currently loaded in, installed in, or associated with the active profile 369 depending on the which flag. 370 371 The default value is used if which is invalid. 372 373 @param which: Which names to get, one of the UIE_ constants in 374 L{AEConstants} 375 @type which: integer 376 @return: Names of all L{AEOutput} and L{AEInput} devices 377 @rtype: list of string 378 ''' 379 if which != AEConstants.UIE_LOADED: 380 return self._getDescriptions(UIRegistrar.DEVICE, which) 381 else: 382 return [dev.getDescription() for dev in self.device_man.getDevices()]
383
385 ''' 386 Gets the programmatic class names of all L{AEMonitor}s currently loaded in, 387 installed in, or associated with the active profile depending on the which 388 flag. 389 390 The default value is used if which is invalid. 391 392 @param which: Which names to get, one of the UIE_ constants in 393 L{AEConstants} 394 @type which: integer 395 @return: Names of all L{AEMonitor} classes 396 @rtype: list of string 397 ''' 398 if which != AEConstants.UIE_LOADED: 399 return self._getClassNames(UIRegistrar.MONITOR, which) 400 else: 401 return [mon.getClassName() for mon in 402 self._getUIEInstances(UIRegistrar.MONITOR, which)]
403
404 - def getMonitorNames(self, which=AEConstants.UIE_LOADED):
405 ''' 406 Gets the human readable names of all L{AEMonitor}s currently loaded in, 407 installed in, or associated with the active profile depending on the which 408 flag. 409 410 The default value is used if which is invalid. 411 412 @param which: Which names to get, one of the UIE_ constants in 413 L{AEConstants} 414 @type which: integer 415 @return: Names of all L{AEMonitor}s 416 @rtype: list of string 417 ''' 418 if which != AEConstants.UIE_LOADED: 419 return self._getNames(UIRegistrar.MONITOR, which) 420 else: 421 return [mon.getName() for mon in 422 self._getUIEInstances(UIRegistrar.MONITOR, which)]
423
425 ''' 426 Gets the human readable descriptions of all L{AEMonitor}s currently loaded 427 in, installed in, or associated with the active profile depending on the 428 which flag. 429 430 The default value is used if which is invalid. 431 432 @param which: Which names to get, one of the UIE_ constants in 433 L{AEConstants} 434 @type which: integer 435 @return: Descriptions of all L{AEMonitor}s 436 @rtype: list of string 437 ''' 438 if which != AEConstants.UIE_LOADED: 439 return self._getDescriptions(UIRegistrar.MONITOR, which) 440 else: 441 return [mon.getDescription() for mon in 442 self._getUIEInstances(UIRegistrar.MONITOR, which)]
443
445 ''' 446 Gets the programmatic class names of all L{AEChooser}s installed in or 447 associated with the active profile depending on the which flag. 448 449 The default value is used if which is invalid. 450 451 @note: Getting loaded chooser names is not currently supported. 452 @param which: Which names to get, one of the UIE_ constants in 453 L{AEConstants} 454 @type which: integer 455 @return: Names of all L{AEChooser} classes 456 @rtype: list of string 457 ''' 458 if which != AEConstants.UIE_LOADED: 459 return self._getClassNames(UIRegistrar.CHOOSER, which)
460
462 ''' 463 Gets the human readable names of all L{AEChooser}s installed in or 464 associated with the active profile depending on the which flag. 465 466 The default value is used if which is invalid. 467 468 @note: Getting loaded chooser names is not currently supported. 469 @param which: Which names to get, one of the UIE_ constants in 470 L{AEConstants} 471 @type which: integer 472 @return: Names of all L{AEChooser}s 473 @rtype: list of string 474 ''' 475 if which != AEConstants.UIE_LOADED: 476 return self._getNames(UIRegistrar.CHOOSER, which)
477
479 ''' 480 Gets the descriptions of all L{AEChooser}s installed in or associated with 481 the active profile depending on the which flag. 482 483 The default value is used if which is invalid. 484 485 @note: Getting loaded chooser names is not currently supported. 486 @param which: Which names to get, one of the UIE_ constants in 487 L{AEConstants} 488 @type which: integer 489 @return: Descriptions of all L{AEChooser}s 490 @rtype: list of string 491 ''' 492 if which != AEConstants.UIE_LOADED: 493 return self._getDescriptions(UIRegistrar.CHOOSER, which)
494
495 - def getPerkClassNames(self, which=AEConstants.UIE_LOADED):
496 ''' 497 Gets the programmatic class names of all L{Perk}s in this L{Tier}, all 498 installed L{Perk}s, L{Perk}s associated with this L{Tier}, or all L{Perk}s 499 associated with this profile depending on the which flag. 500 501 The default value is used if which is invalid. 502 503 @param which: Which names to get, one of the UIE_ constants in 504 L{AEConstants} 505 @type which: integer 506 @return: Names of all L{Perk} classes 507 @rtype: list of string 508 ''' 509 if which != AEConstants.UIE_LOADED: 510 return self._getClassNames(UIRegistrar.PERK, which) 511 else: 512 return [perk.getClassName() for perk in self.tier.getPerks()]
513
514 - def getPerkNames(self, which=AEConstants.UIE_LOADED):
515 ''' 516 Gets the human readable names of all L{Perk}s in this L{Tier}, all 517 installed L{Perk}s, L{Perk}s associated with this L{Tier}, or all L{Perk}s 518 associated with this profile depending on the which flag. 519 520 The default value is used if which is invalid. 521 522 @param which: Which names to get, one of the UIE_ constants in 523 L{AEConstants} 524 @type which: integer 525 @return: Names of all L{Perk}s 526 @rtype: list of string 527 ''' 528 if which != AEConstants.UIE_LOADED: 529 return self._getNames(UIRegistrar.PERK, which) 530 else: 531 return [perk.getName() for perk in self.tier.getPerks()]
532
534 ''' 535 Gets the human readable descriptions of all L{Perk}s in this L{Tier}, all 536 installed L{Perk}s, L{Perk}s associated with this L{Tier}, or all L{Perk}s 537 associated with this profile depending on the which flag. 538 539 The default value is used if which is invalid. 540 541 @param which: Which names to get, one of the UIE_ constants in 542 L{AEConstants} 543 @type which: integer 544 @return: Descriptions of all L{Perk}s 545 @rtype: list of string 546 ''' 547 if which != AEConstants.UIE_LOADED: 548 return self._getDescriptions(UIRegistrar.PERK, which) 549 else: 550 return [perk.getDescription() for perk in self.tier.getPerks()]
551
552 - def registerTask(self, task):
553 ''' 554 Universal task registration method. Uses known interfaces to try to 555 register the given L{Task} as an event task, an input task, a timer task, 556 etc. All information for configuring the L{Task} is contained in the 557 task itself. 558 559 @param task: Task to register 560 @type task: L{Task.Base.Task} 561 @raise NotImplementedError: When the L{Task} does not properly implement 562 the interfaces it should 563 ''' 564 count = 0 565 try: 566 # first try as an event task 567 self.perk.registerEventTask(task, *task.getEventLayers()) 568 count += 1 569 except (AttributeError, NotImplementedError): 570 pass 571 try: 572 # then try as a timer task 573 self.perk.registerTimerTask(task, task.getTimerInterval()) 574 count += 1 575 except AttributeError: 576 pass 577 try: 578 # now try as a named task 579 self.perk.registerNamedTask(task, task.getIdentity()) 580 count += 1 581 except (AttributeError, ValueError): 582 pass 583 if count == 0: 584 # not any kind of known task 585 raise NotImplementedError
586
587 - def unregisterTask(self, task):
588 ''' 589 Universal task unregistration method. Uses known interfaces to try to 590 unregister the given L{Task} as an event task, an input task, a timer task, 591 etc. All information for configuring the L{Task} is contained in the 592 task itself. 593 594 @param task: Task to unregister 595 @type task: L{Task.Base.Task} 596 @raise NotImplementedError: When the L{Task} does not properly implement 597 the interfaces it should 598 ''' 599 count = 0 600 perk = self.perk 601 try: 602 # first try as an event task 603 perk.unregisterEventTask(task, *task.getEventLayers()) 604 count += 1 605 except AttributeError: 606 pass 607 try: 608 # then try as a timer task 609 # make sure it's a timer task first 610 task.getTimerInterval 611 perk.unregisterTimerTask(task) 612 count += 1 613 except AttributeError: 614 pass 615 try: 616 # now try as a named task 617 perk.unregisterNamedTask(task.getIdentity()) 618 count += 1 619 except (AttributeError, ValueError, KeyError): 620 pass 621 if not count: 622 # not any kind of known task 623 raise NotImplementedError
624
625 - def chainTask(self, name, link, target):
626 ''' 627 Chains the L{Task} with the given name to the target L{Task}. If link is 628 CHAIN_BEFORE, the linked L{Task} will execute before the target. If link is 629 CHAIN_AFTER, the linked L{Task} will execute after. If link is 630 CHAIN_AROUND, the linked L{Task} will execute in lieu of the target, but 631 can execute the target manually using L{doTask}. 632 633 @param target: Name of the L{Task} to link to 634 @type target: string 635 @param link: One of the CHAIN constants in L{AEConstants.Tools} 636 @type link: integer 637 @param name: Name of the L{Task} to link 638 @type name: string 639 ''' 640 self.perk.linkTaskToChain(name, link, target)
641
642 - def unchainTask(self, name, link, target):
643 ''' 644 Unchains the L{Task} with the given name to the target L{Task}. The link 645 parameter has the same meaning as in L{chainTask}. If link is set to None, 646 one reference to the named L{Task} is removed from the before, after, and 647 around chains. 648 649 @note: The target L{Task} must be registered at the time of invocation. 650 @param target: Name of the L{Task} to unlink from 651 @type target: string 652 @param link One of the CHAIN constants in L{AEConstants.Tools} or None 653 @type link: integer 654 @param name: Name of the L{Task} to unlink 655 @type name: string 656 @raise ValueError: When the named L{Task} is not unlinked at least once 657 @raise KeyError: When the target L{Task} does not have a chain segement in 658 this L{Perk} for the given link type 659 ''' 660 self.perk.unlinkTaskFromChain(name, link, target)
661
662 - def getTierNamedTask(self, name):
663 ''' 664 Gets the L{Task} with the given name if it is registered anywhere in the 665 current L{Tier}. If no L{Task} is registered under the given name, returns 666 None. 667 668 Calls L{Tier.Tier.getNamedTask} to search across all L{Perk}s in the owning 669 L{Tier}. 670 671 @param name: Name of the L{Task} to locate 672 @type name: string 673 @return: L{Task} with the given name or None 674 @rtype: L{Task.Base.Task} 675 ''' 676 return self.tier.getNamedTask(name)
677
678 - def getTierEventTasks(self, event_type, task_layer):
679 ''' 680 Gets all registered L{Task}s registered to handle the given L{AEEvent} type 681 on the given layer from the current L{Tier}. 682 683 Calls L{Tier.Tier.getEventTasks} to search across all L{Perk}s in the 684 owning L{Tier}. 685 686 @param event_type: Desired type of L{AEEvent} 687 @type event_type: L{AEEvent} class 688 @param task_layer: Layer on which the desired L{Task}s are registered 689 @type task_layer: integer 690 @return: List of all L{Task}s that handle the given event type and on 691 the given layer in the L{Tier} which owns this L{Perk} 692 @rtype: list of L{Task.Base.Task} 693 ''' 694 return self.tier.getEventTasks(event_type, task_layer)
695
696 - def getNamedTask(self, name):
697 ''' 698 Gets the L{Task} with the given name if it is registered B{in this L{Perk} 699 only}. If no L{Task} is registered under the given name in this L{Perk}, 700 returns None. 701 702 @param name: Name of the L{Task} to locate 703 @type name: string 704 @return: L{Task} with the given name or None 705 @rtype: L{Task.Base.Task} 706 @see: L{getTierNamedTask} 707 ''' 708 return self.perk.getNamedTask(name)
709
710 - def getEventTasks(self, event_type, task_layer):
711 ''' 712 Get all registered L{Task}s registered to handle the given L{AEEvent} type 713 B{in this L{Perk} only}. 714 715 @param event_type: Desired type of L{AEEvent} 716 @type event_type: L{AEEvent} class 717 @param task_layer: Layer on which the desired L{Task}s are registered 718 @type task_layer: integer 719 @return: List of all L{Task}s that handle the given event type on the given 720 layer in this L{Perk} 721 @rtype: list of L{Task.Base.Task} 722 @see: L{getTierEventTasks} 723 ''' 724 return self.perk.getEventTasks(event_type, task_layer)
725
726 - def getDeviceState(self, device_name):
727 ''' 728 Gets the default L{AEState} associated with an L{AEOutput} or L{AEInput} 729 device currently loaded in the L{DeviceManager}. 730 731 @param device_name: Name of the device 732 @type device_name: string 733 @return: Loaded state for the device 734 @rtype: L{AEState} 735 ''' 736 try: 737 dev = self.getOutputDevice(device_name) 738 except InvalidDeviceError: 739 return None 740 return dev.getDefaultStyle()
741
742 - def getPerkState(self, perk_name, reload=True):
743 ''' 744 Gets the L{AEState} associated with a L{Perk}. If the state was previously 745 persisted to disk, it is loaded from disk. If not, a new state object 746 is created for the named Perk and immediately persisted in the user's 747 profile. 748 749 @param perk_name: Name of the L{Perk} 750 @type perk_name: string 751 @return: Loaded state for the L{Perk} 752 @rtype: L{AEState} 753 ''' 754 if not reload: 755 perk = self.getPerkByName(perk_name) 756 return perk.getState() 757 758 # load an instance of the perk 759 perk = UIRegistrar.loadOne(perk_name) 760 if perk is None: 761 # quit if we couldn't load the perk 762 return None 763 # create a new empty state object 764 state = perk.getState() 765 # try to load previously persisted state 766 try: 767 return self.sett_man.loadState(perk_name, state) 768 except KeyError: 769 pass 770 # persist a new state instance if it does not exist 771 self.sett_man.saveState(perk_name, state) 772 return state
773
774 - def loadAllMonitors(self):
775 ''' 776 Loads and shows all L{AEMonitor}s associated with this profile. 777 778 @return: Was at least one monitor loaded? 779 @rtype: boolean 780 ''' 781 loaded = False 782 reg = UIRegistrar 783 mons = reg.loadAssociated(UIRegistrar.MONITOR, self.acc_eng.getProfile()) 784 emons = self.event_man.getMonitors() 785 imons, omons = self.device_man.getMonitors() 786 tmons = self.tier_man.getMonitors() 787 if not len(emons): 788 self.event_man.addMonitors(*mons) 789 loaded = True 790 if not len(tmons): 791 self.tier_man.addMonitors(*mons) 792 loaded = True 793 if not (len(imons) + len(omons)): 794 self.device_man.addMonitors(*mons) 795 loaded = True 796 return loaded
797
798 - def unloadAllMonitors(self):
799 ''' 800 Hides and unloads all L{AEMonitor}s associated with this profile. 801 802 @return: Was at least one monitor unloaded? 803 @rtype: boolean 804 ''' 805 unloaded = False 806 emons = self.event_man.getMonitors() 807 imons, omons = self.device_man.getMonitors() 808 tmons = self.tier_man.getMonitors() 809 for mon in (emons, imons, omons, tmons): 810 if len(mon): 811 mon.clear() 812 unloaded = True 813 return unloaded
814
815 - def loadMonitor(self, name):
816 ''' 817 Loads and shows one L{AEMonitor}. 818 819 @param name: Class name of the L{AEMonitor} 820 @type name: string 821 ''' 822 mon = UIRegistrar.loadOne(name) 823 self.event_man.addMonitors(mon) 824 self.tier_man.addMonitors(mon) 825 self.device_man.addMonitors(mon)
826
827 - def unloadMonitor(self, name):
828 ''' 829 Hides and unloads one L{AEMonitor}. 830 831 @param name: Class name of the L{AEMonitor} 832 @type name: string 833 ''' 834 emons = self.event_man.getMonitors() 835 tmons = self.tier_man.getMonitors() 836 imons, omons = self.device_man.getMonitors() 837 for mons in (emons, tmons, imons, omons): 838 mons.removeByClassName(name)
839
840 - def loadChooser(self, name, **kwargs):
841 ''' 842 Loads an L{AEChooser} dialog with the given name from disk. Passes the 843 keyword arguments to the init method of the chooser. This method should 844 typically only be invoked by a L{Task.ChooserTask} subclass. 845 846 @param name: UIE name of the chooser 847 @type name: string 848 @param kwargs: Keyword arguments to initialize the chooser 849 @type kwargs: dictionary 850 @return: Reference to the chooser if it was created. If it already existed, 851 None is returned instead. 852 @rtype: L{AEChooser} 853 ''' 854 reg = UIRegistrar 855 chooser = reg.loadOne(name) 856 if chooser is None: 857 return 858 try: 859 # call the chooser to initialize it with a reference to the event manager 860 chooser(self.event_man, self.tier.getIdentity()) 861 except ValueError, ex: 862 # singleton already exists, reactivate 863 ex.args[0].activate(**kwargs) 864 return None 865 else: 866 # call init to let the chooser initialize itself 867 chooser.init(**kwargs) 868 # register to handle events from this chooser 869 self.perk.registerChooserTask(chooser, self) 870 return chooser
871
872 - def unloadChooser(self, chooser):
873 ''' 874 Unloads the given L{AEChooser} dialog. This method should typically only be 875 invoked by a L{Task.ChooserTask} subclass. 876 877 @param chooser: The chooser to unload 878 @type chooser: L{AEChooser} 879 ''' 880 # unregister the task observing this chooser 881 self.perk.unregisterChooserTask(chooser)
882
883 - def doTask(self, task_name, chain=True, propagate=True, layer=None,**kwargs):
884 ''' 885 Immediately executes a L{Task} registered under the given name in this 886 L{Tier}. Keyword arguments for L{Task} execution may be provided. The 887 L{task_por} of this L{Task} is always provided to the L{Task} being 888 executed and this L{Task}'s L{task_por} is updated with the value of the 889 pointer after the other L{Task} has finished execution. 890 891 The chain parameter dictates whether only the named L{Task} is executed 892 (False), or if all other L{Task}s chained to it are as well (True). The 893 propagate parameter determines whether the execute or update method is 894 called on the L{Task}. This param is not typically specified by a L{Task} 895 or L{Perk}. It is used internally by L{Task.CyclicInputTask} to handle the 896 propagation flag in Task chains. 897 898 @param task_name: Name of the L{Task} to execute 899 @type task_name: string 900 @param chain: Execute all L{Task}s chained to the one named or just the 901 one named? 902 @type chain: boolean 903 @param propagate: Should chained L{Task}s be executed (True) or updated 904 (False)? 905 @type propagate: boolean 906 @param layer: Event layer on which the L{Task} will execute. Defaults to 907 the same layer as the caller if None. 908 @type layer: integer 909 @param kwargs: Arbitrary keyword arguments to pass to the L{Task}, some of 910 which may be required, others which may be optional, and others which 911 may be completely ignored 912 @type kwargs: dictionary 913 ''' 914 # use the current layer if one is not specified 915 if layer is None: layer = self.layer 916 # make sure a Task exists with the given name 917 task = self.tier.getNamedTask(task_name) 918 if task is not None: 919 perk = task.getPerk() 920 self.tier.manageChain(self.task_por, task_name, task, perk, layer, 921 kwargs, propagate, chain) 922 # use the pointer as the new task por 923 self.task_por = self.tier.getPointer()
924
925 - def blockNTasks(self, n, task_type, condition=lambda **x: True):
926 ''' 927 Blocks L{Task}s of the given type from executing in response to the next 928 n events. This is a convenience shortcut to avoid registering one-shot 929 L{Task}s in L{Perk}s to do exactly the same thing. 930 931 @param n: Number of events to block 932 @type n: integer 933 @param task_type: Kind of L{Task} to block 934 @type task_type: L{Task} class 935 @param condition: Condition statement to check if the event is actually 936 one to be consumed. The callable is called with the keyword arguments 937 passed to the L{Task} execute method. 938 @type condition: callable 939 ''' 940 # define an anonymous class of the given type 941 class consumer(task_type): 942 def init(self): 943 self.count = n
944 def execute(self, **kwargs): 945 if not condition(**kwargs): 946 return 947 self.count -= 1 948 if self.count == 0: 949 self.unregisterTask(self) 950 return False
951 # register an instance as a blocker 952 self.registerTask(consumer(None)) 953
954 - def associatePerk(self, name, tier=None, all_tiers=False, index=None):
955 ''' 956 Associates a L{Perk} with the active profile. 957 958 @param name: Name of the UIE to associate 959 @type name: string 960 @param tier: Name of the L{Tier} with which the L{Perk} will be associated. 961 Defaults to the name of the L{Tier} specified by the L{Perk} itself. 962 @type tier: string 963 @param all_tiers: Should the L{Perk} be loaded on every L{Tier}? Defaults 964 to the value specified by the L{Perk} itself. 965 @type all_tiers: boolean 966 @param index: Load order index of the L{Perk}. Lower means sooner to load 967 but also later to handle events (i.e. bottom of the L{Perk} stack). 968 @type index: integer 969 ''' 970 UIRegistrar.associate(name, [self.getProfileName()], tier, all_tiers,index)
971
972 - def disassociatePerk(self, name, tier=None, all_tiers=False):
973 ''' 974 Disassociates a L{Perk} from the active profile. 975 976 @param name: Name of the UIE to disassociate 977 @type name: string 978 @param tier: Name of the L{Tier} from which the L{Perk} will be 979 disassociated. Defaults to the name of the L{Tier} specified by the 980 L{Perk} itself. 981 @type tier: string 982 @param all_tiers: Should the L{Perk} be removed from the list of Perks to 983 load for every L{Tier}? Defaults to the value specified by the L{Perk} 984 itself. 985 ''' 986 UIRegistrar.disassociate(name, [self.getProfileName()], tier, all_tiers)
987
988 - def associateMonitor(self, name):
989 ''' 990 Associates a L{AEMonitor} with the active profile. Loads it immediately. 991 992 @param name: Name of the UIE to associate 993 @type name: string 994 ''' 995 UIRegistrar.associate(name, [self.getProfileName()]) 996 self.loadMonitor(name)
997
998 - def disassociateMonitor(self, name):
999 ''' 1000 Associates a L{AEMonitor} with the active profile. Unloads it immediately. 1001 1002 @param name: Name of the UIE to associate 1003 @type name: string 1004 ''' 1005 self.unloadMonitor(name) 1006 UIRegistrar.disassociate(name, [self.getProfileName()])
1007
1008 - def associateDevice(self, name, index=None):
1009 ''' 1010 Associates a L{AEOutput} or L{AEInput} device with the active profile. 1011 Does not load it immediately. See L{refreshDevices} for that functionality. 1012 1013 @param name: Name of the UIE to associate 1014 @type name: string 1015 @param index: Load order index of the device where lower means sooner, None 1016 means last. 1017 @type index: integer 1018 ''' 1019 UIRegistrar.associate(name, [self.getProfileName()], index=index)
1020
1021 - def disassociateDevice(self, name):
1022 ''' 1023 Disassociates a L{AEOutput} or L{AEInput} device from the active profile. 1024 Does not unload it immediately. See L{refreshDevices} for that 1025 functionality. 1026 1027 @param name: Name of the UIE to associate 1028 @type name: string 1029 ''' 1030 UIRegistrar.disassociate(name, [self.getProfileName()])
1031
1032 - def refreshDevices(self):
1033 ''' 1034 Unloads all existing devices then immediately loads all devices associated 1035 with the active profile. 1036 ''' 1037 self.device_man.unloadDevices() 1038 self.device_man.loadDevices()
1039
1040 - def setTempVal(self, name, value):
1041 ''' 1042 Stores the given value under the given name. The data will be available via 1043 L{getTempVal} to all L{Task}s executing or updating in response to the 1044 current L{AEEvent}. This includes cascading L{Task.EventTask}s, chained 1045 L{Task.InputTask}s with names, etc. Once the event has been handled by all 1046 L{Task}s, all stored information is discarded automatically. 1047 1048 The name must be an immutable object. The value can be an arbitrary object. 1049 Only the value from the most recent call with a given name is stored. 1050 1051 @param name: Name to associate with the value 1052 @type name: immutable 1053 @param value: Any value to store 1054 @type value: object 1055 ''' 1056 self.tier.setTempVal(name, value)
1057
1058 - def getTempVal(self, name):
1059 ''' 1060 Gets the value previously stored under the given name using L{setTempVal}. 1061 See that method for details. 1062 1063 If no value has been stored under the given name, None is returned. 1064 1065 @param name: Name of the stored data 1066 @type name: immutable 1067 @return: Value stored under the given name or None 1068 @rtype: object 1069 ''' 1070 try: 1071 return self.tier.getTempVal(name) 1072 except KeyError: 1073 return None
1074
1075 - def registerConstants(self, scope, *names):
1076 ''' 1077 Adds new constants to L{AEConstants} such that they are visible to other 1078 L{Perk}s. If any of the named constants do not exist, an exception will 1079 be raised. If any of the named constants are already registered, they will 1080 be silently ignored by L{AEConstants.register}. 1081 1082 @param scope: Scope in which the constants are defined (e.g. globals()) 1083 @type scope: dictionary 1084 @param names: Names of constants to register 1085 @type names: list of string 1086 @raise KeyError: When one of the named constants does not exist in the 1087 scope 1088 ''' 1089 AEConstants.register(dict(((name, scope[name]) for name in names)))
1090
1091 - def getPerkByName(self, name):
1092 ''' 1093 Gets the L{Perk} with the given name. 1094 1095 If no perk is registered under the given name, KeyError is raised. 1096 1097 @param name: Name of the perk 1098 @type name: string 1099 @return: Perk with the given name 1100 @rtype: object 1101 @raise KeyError: When the perk with the given name is not found 1102 ''' 1103 for perk in self.tier.getPerks(): 1104 if perk.getClassName() == name: 1105 return perk 1106 raise KeyError
1107
1108 - def getPerkVar(self, perk_name, var_name):
1109 ''' 1110 Gets the L{Perk} instance variable with the given name. 1111 1112 If no perk is registered under the given name a KeyError is raised 1113 if the perk does not contain var_name an AttributeError is raised. 1114 1115 @param perk_name: Name of the perk 1116 @type perk_name: immutable 1117 @param var_name: Name of the instance variable 1118 @type var_name: immutable 1119 @return: perk variable with the given name 1120 @rtype: object 1121 @raise KeyError: When the perk or variable with it's given name 1122 is not found 1123 @raise AttributeError: When attribute is not found 1124 is not found 1125 ''' 1126 perk = self.getPerkByName(perk_name) 1127 return getattr(perk, var_name)
1128
1129 - def setPerkVar(self, perk_name, var_name, value):
1130 ''' 1131 Sets the L{Perk} instance variable with the given name to value. 1132 1133 If no perk is registered under the given name a KeyError is raised 1134 if the perk does not contain var_name an AttributeError is raised. 1135 1136 @param perk_name: Name of the perk 1137 @type perk_name: immutable 1138 @param var_name: Name of the instance variable 1139 @type var_name: immutable 1140 @param value: value to set instance variable 1141 @type value: immutable 1142 @return: perk variable with the given name 1143 @rtype: object 1144 @raise KeyError: When the perk or variable with it's given name 1145 @raise AttributeError: When attribute is not found 1146 ''' 1147 perk = self.getPerkByName(perk_name) 1148 setattr(perk, var_name, value)
1149
1150 - def getPerkSetting(self, setting_name, perk_name=None):
1151 ''' 1152 Gets the L{Perk} L{Setting} state variable with the given name. 1153 1154 If no perk is registered under the given name or L{setting_name} is not 1155 found, KeyError is raised. 1156 1157 @param perk_name: Name of the perk 1158 @type perk_name: immutable 1159 @param setting_name: Name of the perk 1160 @type setting_name: immutable 1161 @return: L{Setting} object for given perk. 1162 @rtype: object 1163 @raise KeyError: When the perk is not found 1164 ''' 1165 if perk_name is None: 1166 perk_name = self.perk.getClassName() 1167 state = self.getPerkState(perk_name, reload=False) 1168 return state.getSettingObj(setting_name)
1169
1170 - def getPerkSettingVal(self, setting_name, perk_name=None):
1171 ''' 1172 Gets the value of the L{Perk} L{Setting} state variable with the given 1173 name. 1174 1175 If no perk is registered under the given name or if L{setting_name} is not 1176 found, KeyError is raised. 1177 1178 @param perk_name: Name of the perk 1179 @type perk_name: immutable 1180 @param setting_name: Name of the perk 1181 @type setting_name: immutable 1182 @return: value contained in L{AEState} attribute with given name 1183 @rtype: object 1184 @raise KeyError: When the perk is not found 1185 ''' 1186 if perk_name is None: 1187 perk_name = self.perk.getClassName() 1188 state = self.getPerkState(perk_name, reload=False) 1189 return state.getSettingVal(setting_name)
1190
1191 - def setPerkSettingVal(self, setting_name, value, perk_name=None):
1192 ''' 1193 Sets the value of the L{Perk} L{Setting} state variable with the given 1194 name. 1195 1196 If no perk is registered under the given name or if L{setting_name} is not 1197 found, KeyError is raised. 1198 1199 @param perk_name: Name of the perk 1200 @type perk_name: immutable 1201 @param setting_name: Name of the perk 1202 @type setting_name: immutable 1203 @param value: value contained in L{AEState} attribute with given name 1204 @param value: object 1205 @raise KeyError: When the L{Perk} is not found 1206 ''' 1207 if perk_name is None: 1208 perk_name = self.perk.getClassName() 1209 state = self.getPerkState(perk_name, reload=False) 1210 state.setSettingVal(setting_name, value)
1211
1212 - def getHistory(self):
1213 ''' 1214 Gets the zipped contents of L{getTaskHistory} and L{getPerkHistory}. This 1215 method does not involve extra processing because the history is already 1216 zipped in the L{Tier}. In fact, the other methods require the extra work 1217 of unzipping. 1218 1219 The history is ordered from the first L{Task} to respond to an event to 1220 the most recent L{Task} to respond, including the current L{Task}. 1221 1222 @return: List of L{Task} identities and L{Perk} class names 1223 @rtype: list of 2-tuple of string 1224 ''' 1225 return self.tier.getHistory()
1226
1227 - def getTaskHistory(self):
1228 ''' 1229 Gets the identities of all L{Task}s that have executed in response to the 1230 event currently being processed. This includes all chained L{Task}s and all 1231 L{Task}s executed using L{doTask} flattened into a linear history. 1232 1233 If any L{Task} that executed did not have an identity, None is substituted 1234 in its place. 1235 1236 The history is ordered from the first L{Task} to respond to an event to 1237 the most recent L{Task} to respond, including the current L{Task}. 1238 1239 @return: Identities of the L{Task}s 1240 @rtype: list of string 1241 ''' 1242 h = self.tier.getHistory() 1243 return [names[0] for names in h]
1244
1245 - def getPerkHistory(self):
1246 ''' 1247 Gets the class names of all L{Perk}s that have executed in response to the 1248 event currently being processed. The contents of the list returned by this 1249 method have a one-to-one pairing with the list contents from 1250 L{getTaskHistory}. 1251 1252 The history is ordered from the first L{Perk} to respond to an event to 1253 the most recent L{Perk} to respond, including the current L{Perk}. 1254 1255 @return: Class names of the L{Perk}s 1256 @rtype: list of string 1257 ''' 1258 h = self.tier.getHistory() 1259 return [names[1] for names in h]
1260
1261 - def getAnchorTaskId(self):
1262 ''' 1263 Gets the identity of the L{Task} which this one is executing before, after, 1264 or around according to a previous chaining. If this L{Task} is not 1265 executing as part of a chain, returns None. 1266 1267 @return: Identity of the L{Task} or None 1268 @rtype: string 1269 ''' 1270 try: 1271 return self.tier.getAnchor()[0] 1272 except TypeError: 1273 return None
1274
1275 - def getAnchorPerkClassName(self):
1276 ''' 1277 Gets the class name of the L{Perk} owning the L{Task} that would be 1278 returned by L{getAnchorTaskId}. 1279 1280 @see: L{getAnchorTaskId} 1281 @return: Class name of the L{Perk} or None 1282 @rtype: string 1283 ''' 1284 try: 1285 return self.tier.getAnchor()[1] 1286 except TypeError: 1287 return None
1288
1289 - def getPerkTaskNames(self, perk_name=None):
1290 ''' 1291 Gets the names of all L{Task}s currently registered in the named L{Perk}. 1292 If no name is given, this L{Perk} is used. If the named L{Perk} is not 1293 found, an exception is raised. 1294 1295 @param perk_name: Name of the L{Perk} to query or None to mean this one 1296 @type perk_name: string 1297 @return: List of all registered L{Task} names 1298 @rtype: list of string 1299 @raise KeyError: When the named L{Perk} is not loaded 1300 ''' 1301 if perk_name is None: 1302 return self.perk.getTaskNames() 1303 else: 1304 for perk in self.tier.getPerks(): 1305 if perk.getClassName() == perk_name: 1306 return perk.getTaskNames() 1307 raise KeyError(perk_name)
1308
1309 - def getTierTaskNames(self):
1310 ''' 1311 Gets the names of all L{Task}s currently registered in this L{Tier}. 1312 1313 @return: List of all registered L{Task} names 1314 @rtype: list of string 1315 ''' 1316 names = [] 1317 for perk in self.tier.getPerks(): 1318 names.extend(perk.getTaskNames()) 1319 return names
1320