root / org.gvsig.educa.batovi / trunk / org.gvsig.educa.batovi.mapviewer / org.gvsig.educa.batovi.mapviewer.activity / skeleton / MapViewerActivity.py @ 133
History | View | Annotate | Download (10.7 KB)
1 |
import os, shutil, stat |
---|---|
2 |
import gtk, gobject |
3 |
import popen2 |
4 |
from os import path as Path |
5 |
|
6 |
import logging |
7 |
import sugar.activity.activity as activity |
8 |
from sugar.activity.activity import Activity |
9 |
from sugar.datastore import datastore |
10 |
|
11 |
"""
|
12 |
Alternative paths to locate JRE
|
13 |
"""
|
14 |
JAVA_HOME_PATHS=( |
15 |
#"/usr/lib/jvm/jre", # gcj path DOESN'T WORK!!!
|
16 |
str(Path.join(Path.expanduser("~"),"Activities/Java.activity/jre")), # Java activity path |
17 |
) |
18 |
|
19 |
# LOG level config
|
20 |
logging.basicConfig(level=logging.DEBUG) |
21 |
#logging.basicConfig(level=logging.INFO)
|
22 |
|
23 |
|
24 |
"""
|
25 |
gvSIG batovi MapViewer activity
|
26 |
|
27 |
Requires:
|
28 |
|
29 |
* Sugar builds > 706
|
30 |
|
31 |
* A java installed or the Java activity installed
|
32 |
|
33 |
For more information see: http://www.mediagala.com/rap/foro/viewtopic.php?f=8&t=166
|
34 |
|
35 |
On first _run_ executes son post-install actions.
|
36 |
|
37 |
"""
|
38 |
class MapViewerActivity(Activity): |
39 |
# viewer activity path (where is gvSIG activity)
|
40 |
viewer_activity=None
|
41 |
|
42 |
# viewer Home path (where is gvSIG installation)
|
43 |
viewer_home=None
|
44 |
|
45 |
|
46 |
#Java Home
|
47 |
java_home=None
|
48 |
|
49 |
|
50 |
def __init__(self, handle): |
51 |
logging.debug('Creating MapViewer handler.')
|
52 |
|
53 |
Activity.__init__(self, handle)
|
54 |
self.handle = handle
|
55 |
|
56 |
# Register run() to run from gtk_main_loop
|
57 |
# as soon as it gets idle.
|
58 |
# Which is kludge to make it run after the loop has begun
|
59 |
self.idleFunc = gobject.idle_add(self.run) |
60 |
|
61 |
def run(self): |
62 |
# Remove run() because we want it to run only once
|
63 |
gobject.source_remove(self.idleFunc)
|
64 |
|
65 |
# locate and check jre
|
66 |
if not self.initializeJavaHome(): |
67 |
# Exiting with a error
|
68 |
self.showMessageError("Can't found any JRE to run MapViewer:\nSee http://www.mediagala.com/rap/foro/viewtopic.php?f=8&t=166\nfor more information") |
69 |
logging.error("No JRE found!!!")
|
70 |
logging.debug("Closing activity");
|
71 |
self.close(True) |
72 |
return
|
73 |
|
74 |
# setup environ properties
|
75 |
self.viewer_activity=activity.get_bundle_path()
|
76 |
self.viewer_home=Path.join(self.viewer_activity, 'viewer') |
77 |
|
78 |
os.environ['VIEWER_HOME']=self.viewer_home |
79 |
os.environ['VIEWER_ACTIVITY']=self.viewer_activity |
80 |
os.environ['JAVA_HOME']=self.java_home |
81 |
|
82 |
# do post-install actions
|
83 |
self.postInstall()
|
84 |
|
85 |
# identify gvSIG launcher
|
86 |
viewer_sh = Path.join(self.viewer_home, 'mapViewer.sh') |
87 |
|
88 |
if not Path.exists(viewer_sh): |
89 |
raise Exception("Missing launcher: %s" % viewer_sh) |
90 |
|
91 |
# check execution permission
|
92 |
self.fixExcecutionFilePermission(viewer_sh)
|
93 |
|
94 |
try:
|
95 |
logging.info("Executing '%s'" % viewer_sh);
|
96 |
|
97 |
# execute gvSIG.sh
|
98 |
gvSIG_process = popen2.Popen4('%s' % viewer_sh, 16) |
99 |
|
100 |
# writing stout in log file
|
101 |
logging.info(gvSIG_process.fromchild.read()) |
102 |
|
103 |
# wait until gvSIG exit
|
104 |
rcode = gvSIG_process.wait() |
105 |
|
106 |
logging.info('mapViewer.sh returned with code=%d' % rcode)
|
107 |
|
108 |
finally:
|
109 |
logging.debug("Closing activity");
|
110 |
self.close(True) |
111 |
|
112 |
def showMessageError(self, message): |
113 |
md = gtk.MessageDialog(self,
|
114 |
gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, |
115 |
gtk.BUTTONS_CLOSE, message) |
116 |
md.run() |
117 |
md.destroy() |
118 |
|
119 |
"""
|
120 |
Initialize property ``java_home``
|
121 |
|
122 |
Try to locate a valid java in ``JAVA_HOME_PATHS`` list
|
123 |
|
124 |
Check that existe a *bin/java* executable file inside of it.
|
125 |
|
126 |
If not JRE found returns False. Otherwise returns True
|
127 |
"""
|
128 |
def initializeJavaHome(self): |
129 |
for jhome in JAVA_HOME_PATHS: |
130 |
logging.debug("check jre in %s" % jhome)
|
131 |
if not Path.exists(jhome): |
132 |
logging.debug("%s not found" % jhome)
|
133 |
continue
|
134 |
if self.checkJavaExecutable(jhome): |
135 |
self.java_home=jhome
|
136 |
logging.debug("ussing '%s' for JAVA_HOME" % jhome)
|
137 |
return True |
138 |
else:
|
139 |
logging.debug("No Java available in register paths: %s" % repr(JAVA_HOME_PATHS)) |
140 |
return False |
141 |
|
142 |
|
143 |
|
144 |
|
145 |
"""
|
146 |
Check ``javaHome`` folder: check that exist a *bin/java* executable file
|
147 |
|
148 |
Returns True/False
|
149 |
"""
|
150 |
def checkJavaExecutable(self, javaHome): |
151 |
javaExe=Path.join(javaHome,"bin","java") |
152 |
if not Path.exists(javaExe): |
153 |
return False |
154 |
return os.access(javaExe, os.X_OK)
|
155 |
|
156 |
"""
|
157 |
Run post install actions.
|
158 |
|
159 |
This actions usually will be execute just once, in first activity run
|
160 |
"""
|
161 |
def postInstall(self): |
162 |
self.installInGvSIGUserHome()
|
163 |
self.installInUserHome()
|
164 |
self.execScripts()
|
165 |
|
166 |
"""
|
167 |
*Post Intall process:* Excecutes install scripts
|
168 |
|
169 |
This actions usually will be execute just once, in first activity run.
|
170 |
"""
|
171 |
def execScripts(self): |
172 |
# check if ther is any file to copy to
|
173 |
sourceFolder = Path.join(activity.get_bundle_path(), 'post-install', 'scripts') |
174 |
|
175 |
if not Path.exists(sourceFolder): |
176 |
# No files to execute
|
177 |
return
|
178 |
|
179 |
everyScriptOk = True
|
180 |
|
181 |
# for all file/dir in souceFolder
|
182 |
scriptFiles = os.listdir(sourceFolder) |
183 |
|
184 |
for aFile in scriptFiles: |
185 |
fext = Path.splitext(aFile)[1]
|
186 |
aFilePath = Path.join(sourceFolder,aFile) |
187 |
if fext == "py": |
188 |
# Exec python script
|
189 |
execOk = self.execPython(aFilePath)
|
190 |
if execOk:
|
191 |
shutil.move(aFilePath,aFilePath+".done")
|
192 |
else:
|
193 |
everyScriptOk=False
|
194 |
|
195 |
|
196 |
elif fext == "sh": |
197 |
# Exec Shell script
|
198 |
execOk = self.execShell(aFilePath)
|
199 |
if execOk:
|
200 |
shutil.move(aFilePath,aFilePath+".done")
|
201 |
else:
|
202 |
everyScriptOk=False
|
203 |
|
204 |
elif fext == "done": |
205 |
# Nothing to do
|
206 |
pass
|
207 |
|
208 |
else:
|
209 |
# Ignoring file
|
210 |
logging.debug("Ignoring post-install script: " + aFilePath)
|
211 |
|
212 |
|
213 |
if everyScriptOk:
|
214 |
# rename folder to avoid execution on next application open
|
215 |
shutil.move(sourceFolder, sourceFolder+".done")
|
216 |
|
217 |
"""
|
218 |
Excecutes a python script file
|
219 |
"""
|
220 |
def execPython(self,aFile): |
221 |
logging.debug("Executing python script '%s'" % aFile);
|
222 |
try:
|
223 |
# open file in read-only mode
|
224 |
f = file(aFile,"r") |
225 |
|
226 |
# exec script
|
227 |
try:
|
228 |
exec f
|
229 |
finally:
|
230 |
f.close() |
231 |
|
232 |
return True |
233 |
except Exception, exc: |
234 |
logging.error("Excecuting file %s: %s" % (aFile,exc));
|
235 |
return False |
236 |
|
237 |
"""
|
238 |
Fix (set) execution permission of a file
|
239 |
"""
|
240 |
def fixExcecutionFilePermission(self, aFile): |
241 |
# check execution permission
|
242 |
if not os.access(aFile, os.X_OK): |
243 |
# set excecution permission
|
244 |
os.chmod(aFile,os.stat(aFile)+stat.S_IEXEC) |
245 |
|
246 |
"""
|
247 |
Excecutes a shell script file
|
248 |
"""
|
249 |
def execShell(self,aFile): |
250 |
logging.debug("Executing '%s'" % aFile);
|
251 |
try:
|
252 |
mProcess = popen2.Popen4('%s' % aFile, 16) |
253 |
logging.debug(mProcess.fromchild.read()) |
254 |
rcode = mProcess.wait() |
255 |
return rcode == 0 |
256 |
except Exception, exc: |
257 |
logging.error("Excecuting file %s: %s" % (aFile,exc));
|
258 |
return False |
259 |
|
260 |
|
261 |
"""
|
262 |
*Post Intall process:* Install files in user home
|
263 |
|
264 |
Move files from ``{activity_folder}/post-install/user-home`` to ``$HOME``
|
265 |
|
266 |
**NOTE**: if a file/dir already exist **will be ignored** (Keeping untouched original files)
|
267 |
"""
|
268 |
def installInUserHome(self): |
269 |
# check if ther is any file to copy to
|
270 |
sourceFolder = Path.join(activity.get_bundle_path(), 'post-install', 'user-home') |
271 |
|
272 |
if not Path.exists(sourceFolder): |
273 |
# No files to copy
|
274 |
return
|
275 |
|
276 |
homeUserFolder = Path.expanduser("~")
|
277 |
|
278 |
#merge folder
|
279 |
self.mergeFolder(sourceFolder,homeUserFolder)
|
280 |
|
281 |
#rename source folder to prevent rerun of this step
|
282 |
os.rename(sourceFolder,sourceFolder+".done")
|
283 |
|
284 |
#done
|
285 |
return
|
286 |
|
287 |
"""
|
288 |
*Post Intall process:* Install files in the gvSIG user home folder
|
289 |
|
290 |
Move files from ``{activity_folder}/post-install/user-gvsig-home`` to ``$HOME/gvSIG``
|
291 |
"""
|
292 |
def installInGvSIGUserHome(self): |
293 |
# check if ther is any file to copy to
|
294 |
sourceFolder = Path.join(activity.get_bundle_path(), 'post-install', 'user-gvsig-home') |
295 |
|
296 |
if not Path.exists(sourceFolder): |
297 |
# No files to copy
|
298 |
return
|
299 |
|
300 |
homeGvsigUserFolder = Path.expanduser("~/gvSIG")
|
301 |
|
302 |
if not Path.exists(homeGvsigUserFolder): |
303 |
# Create gvSIG user home folder
|
304 |
os.mkdir(homeGvsigUserFolder) |
305 |
|
306 |
|
307 |
#move files
|
308 |
self.mergeFolder(sourceFolder,homeGvsigUserFolder)
|
309 |
|
310 |
#rename source folder to prevent rerun of this step
|
311 |
os.rename(sourceFolder,sourceFolder+".done")
|
312 |
|
313 |
#done
|
314 |
return
|
315 |
|
316 |
"""
|
317 |
Move files from ``sourceFolder`` into ``targetFolder``
|
318 |
|
319 |
``sourceFolder`` must be a folder
|
320 |
``targetFolder`` must be a folder or not exists (so it will be created)
|
321 |
``overrideTarget`` if it's ``False`` raise an exception when target already contains the file/dir to move. if ``ignoreExisting``
|
322 |
``ignoreExisting`` modifies ``overrideTarget`` option (when it's ``False``) to don't raise an exception, just skip file/folder
|
323 |
"""
|
324 |
def moveFiles(self,sourceFolder,targetFolder,overrideTarget=True,ignoreExisting=True): |
325 |
if not Path.exists(targetFolder): |
326 |
# Create target folder
|
327 |
os.makedirs(targetFolder) |
328 |
# set overrideTarget to True because target is new
|
329 |
overrideTarget=True
|
330 |
elif not Path.isdir(targetFolder): |
331 |
raise Exception("%s must be a dir" % targetFolder) |
332 |
|
333 |
# for all file/dir in souceFolder
|
334 |
toMoveList = os.listdir(sourceFolder) |
335 |
for toMove in toMoveList: |
336 |
|
337 |
target = Path.join(targetFolder,toMove) |
338 |
# check if exists target
|
339 |
if Path.exists(target):
|
340 |
if overrideTarget:
|
341 |
if ignoreExisting:
|
342 |
continue
|
343 |
|
344 |
else:
|
345 |
if ignoreExisting:
|
346 |
continue
|
347 |
else:
|
348 |
raise Exception("%s alredy exists in target folder %s" % (toMove, targetFolder)) |
349 |
|
350 |
|
351 |
# move file/dir
|
352 |
shutil.move(Path.join(sourceFolder, toMove), targetFolder) |
353 |
|
354 |
|
355 |
"""
|
356 |
Merge folder content: Copy all missing folders and files from
|
357 |
``sourceFolder`` to ``targetFolder``.
|
358 |
|
359 |
Process doesn't override existing files in ``targetFolder``
|
360 |
"""
|
361 |
def mergeFolder(self,sourceFolder,targetFolder): |
362 |
# get folder contents
|
363 |
names = os.listdir(sourceFolder) |
364 |
|
365 |
if not Path.exists(targetFolder): |
366 |
# Create target folder if not exists
|
367 |
os.makedirs(targetFolder) |
368 |
|
369 |
for name in names: |
370 |
srcname = Path.join(sourceFolder, name) |
371 |
dstname = Path.join(targetFolder, name) |
372 |
if Path.isdir(srcname):
|
373 |
# Recursive call to mergeFolder
|
374 |
self.mergeFolder(srcname,dstname)
|
375 |
else:
|
376 |
if not Path.exists(dstname): |
377 |
# Copy new file
|
378 |
shutil.copy(srcname,dstname) |
379 |
else:
|
380 |
# skip existing file
|
381 |
continue
|
382 |
|
383 |
|
384 |
|
385 |
|
386 |
|