1import sys 2import os 3import glob 4import re 5 6from Keywords import Keyword as Kw, Set as KwS 7from Prophet.Categories import * 8from Prophet import msg 9 10import Prophet 11 12 13class App(Prophet.App): 14 15 """A simple application that may have different executables""" 16 pref = 30 17 18 def __new__(cls): 19 try: 20 self = cls.__inst__ 21 if not self: 22 raise Prophet.NotSet 23 24 except AttributeError: 25 self = cls.__inst__ = object.__new__(cls) 26 try: 27 self.__setup__() 28 except Prophet.NotSet: 29 cls.__inst__ = None 30 raise 31 32 return self 33 34 def setKeywords(self): 35 super(App, self).setKeywords() 36 self.keywords |= KwS(Legacy) 37 38 def setExename(self): 39 # Obtain known executable names for the application 40 try: 41 exes = self.exes 42 except AttributeError: 43 # If none were explicitly specified, use self class name 44 exes = [self.__class__.__name__] 45 prefixes = self.getPrefixes() 46 paths = self.getPaths() 47 valids = [] 48 for x in exes: 49 for pfx, bps in prefixes.binpaths.items(): 50 try: 51 exe = bps.which(x) 52 if self.valid(pfx, exe): 53 valids.append((pfx, exe)) 54 55 except Prophet.NotFound: 56 pass 57 58 try: 59 self.prefix, self.exename = self.select(valids) 60 except Prophet.NotFound: 61 raise Prophet.NotSet 62 63 def valid(self, pfx, exe): 64 return True 65 66 def select(self, valids): 67 if len(valids): 68 return valids[0] 69 else: 70 raise Prophet.NotFound 71 72 73class ConsoleApp(Prophet.App): 74 75 """Mixin class for the console application that must be run in terminal""" 76 77 def setKeywords(self): 78 super(ConsoleApp, self).setKeywords() 79 self.keywords |= KwS(ConsoleOnly) 80 81 82class X11App(Prophet.App): 83 84 """Mixin class for the X11 GUI application""" 85 86 87class ZeroG(App): 88 89 """Application installed by the ZeroG LaunchAnywhere system. 90 This is usually a commercial Java application""" 91 registry = "~/.com.zerog.registry.xml" 92 93 def getPrefixes(self): 94 prefixes = super(ZeroG, self).getPrefixes() 95 try: 96 zerog = open(os.path.expanduser(self.registry), "r") 97 pattern = re.compile( 98 ".*<product.*name=\"(%s)\".*location=\"(.*)\".*last_modified=\"(.*)\".*>.*" % 99 self.magic) 100 found = [] 101 for x in zerog: 102 rx = pattern.match(x) 103 if rx: 104 found.append((rx.group(3), rx.group(1), rx.group(2))) 105 106 zerog.close() 107 found.sort() 108 found.reverse() 109 prefixes = Prophet.PrefixSet([x[2] for x in found]) + prefixes 110 except IOError: 111 pass 112 return prefixes 113 114 115class DropIn(App): 116 117 maxDepth = 3 118 dropRoots = ["~"] 119 120 class StopDescention(Exception): 121 122 def __init__(self, value): 123 self.value = value 124 125 def getPrefixes(self): 126 prefixes = super(DropIn, self).getPrefixes() 127 try: 128 for r in self.dropRoots: 129 self.descend(os.path.expanduser(r), 1) 130 131 except DropIn.StopDescention as e: 132 prefixes += e.value 133 return prefixes 134 135 def descend(self, path, depth): 136 self.relevant(path) 137 if depth > self.maxDepth: 138 return 139 try: 140 for x in os.listdir(path): 141 dir = os.path.join(path, x) 142 if not x.startswith(".") and os.path.isdir(dir): 143 self.descend(dir, depth + 1) 144 145 except OSError: 146 pass 147 148 149__legacy__ = ["Development", "Editor", "Emulator", 150 "Multimedia", "Graphics", "Network", "Shell"] 151 152entries = [] # List of all legacy entries found 153 154 155def _register(module, this=True): 156 """Import and store the specified module along with all its submodules""" 157 try: 158 names = module.__legacy__ 159 except AttributeError: 160 names = [] 161 if this: 162 for k, v in module.__dict__.items(): 163 if not k.startswith("_") and isinstance( 164 v, 165 type) and issubclass( 166 v, 167 Prophet.App): 168 entries.append(v) 169 170 for x in names: 171 name = module.__name__ + "." + x 172 try: 173 __import__(name) 174 except ImportError: 175 raise ImportError("No module named " + name) 176 imp = sys.modules[name] 177 _register(imp) 178 179 180def setup(): 181 _register(sys.modules[__name__], this=False) 182 183 184def scan(): 185 result = [] 186 msg(" legacy...", newline=False) 187 for x in entries: 188 try: 189 result.append(x()) 190 except Prophet.NotSet: 191 pass 192 193 msg(" %d apps found" % len(result)) 194 return result 195