1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import os
24 from Queue import Queue, Empty
25 from threading import Thread, BoundedSemaphore
26 import time
27 import shutil
28 import stat
29
30 from Task import Task
31 import Log
32 import Version
33
35 - def __init__(self, target, name, function, resultQueue, loaderSemaphore, onLoad = None):
36 Thread.__init__(self)
37 self.semaphore = loaderSemaphore
38 self.target = target
39 self.name = name
40 self.function = function
41 self.resultQueue = resultQueue
42 self.result = None
43 self.onLoad = onLoad
44 self.exception = None
45 self.time = 0.0
46 self.canceled = False
47 if target and name:
48 setattr(target, name, None)
49
51 self.semaphore.acquire()
52
53 if os.name == "posix":
54 os.nice(5)
55 self.load()
56 self.semaphore.release()
57 self.resultQueue.put(self)
58
60 return "%s(%s) %s" % (self.function.__name__, self.name, self.canceled and "(canceled)" or "")
61
64
66 try:
67 start = time.time()
68 self.result = self.function()
69 self.time = time.time() - start
70 except:
71 import sys
72 self.exception = sys.exc_info()
73
75 if self.canceled:
76 return
77
78 Log.notice("Loaded %s.%s in %.3f seconds" % (self.target.__class__.__name__, self.name, self.time))
79
80 if self.exception:
81 raise self.exception[0], self.exception[1], self.exception[2]
82 if self.target and self.name:
83 setattr(self.target, self.name, self.result)
84 if self.onLoad:
85 self.onLoad(self.result)
86 return self.result
87
89 self.join()
90 return self.result
91
93 - def __init__(self, dataPath = os.path.join("..", "data")):
94 self.resultQueue = Queue()
95 self.dataPaths = [dataPath]
96 self.loaderSemaphore = BoundedSemaphore(value = 1)
97 self.loaders = []
98
100 if not path in self.dataPaths:
101 self.dataPaths = [path] + self.dataPaths
102
104 if path in self.dataPaths:
105 self.dataPaths.remove(path)
106
108 if not args.get("writable", False):
109 for dataPath in self.dataPaths:
110 readOnlyPath = os.path.join(dataPath, *name)
111
112
113 if os.path.isfile(readOnlyPath):
114 return readOnlyPath
115 readWritePath = os.path.join(getWritableResourcePath(), *name)
116 if os.path.isfile(readWritePath):
117 return readWritePath
118 return readOnlyPath
119 else:
120 readOnlyPath = os.path.join(self.dataPaths[-1], *name)
121 try:
122
123 if os.access(readOnlyPath, os.W_OK):
124 return readOnlyPath
125
126 if not os.path.isfile(readOnlyPath) and os.access(os.path.dirname(readOnlyPath), os.W_OK):
127 return readOnlyPath
128 except:
129 raise
130
131
132
133 readWritePath = os.path.join(getWritableResourcePath(), *name)
134 if not os.path.isfile(readWritePath) and os.path.isfile(readOnlyPath):
135 Log.notice("Copying '%s' to writable data directory." % "/".join(name))
136 try:
137 os.makedirs(os.path.dirname(readWritePath))
138 except:
139 pass
140 shutil.copy(readOnlyPath, readWritePath)
141 self.makeWritable(readWritePath)
142
143 if not os.path.isdir(readWritePath) and os.path.isdir(readOnlyPath):
144 Log.notice("Creating writable directory '%s'." % "/".join(name))
145 os.makedirs(readWritePath)
146 self.makeWritable(readWritePath)
147 return readWritePath
148
150 os.chmod(path, stat.S_IWRITE | stat.S_IREAD | stat.S_IEXEC)
151
152 - def load(self, target = None, name = None, function = lambda: None, synch = False, onLoad = None):
153 Log.notice("Loading %s.%s %s" % (target.__class__.__name__, name, synch and "synchronously" or "asynchronously"))
154 l = Loader(target, name, function, self.resultQueue, self.loaderSemaphore, onLoad = onLoad)
155 if synch:
156 l.load()
157 return l.finish()
158 else:
159 self.loaders.append(l)
160 l.start()
161 return l
162
163 - def run(self, ticks):
164 try:
165 loader = self.resultQueue.get_nowait()
166 loader.finish()
167 self.loaders.remove(loader)
168 except Empty:
169 pass
170
172 """
173 Returns a path that holds the configuration for the application.
174 """
175 path = "."
176 appname = Version.appName()
177 if os.name == "posix":
178 path = os.path.expanduser("~/." + appname)
179 elif os.name == "nt":
180 try:
181 path = os.path.join(os.environ["APPDATA"], appname)
182 except:
183 pass
184 try:
185 os.mkdir(path)
186 except:
187 pass
188 return path
189