Statistics
| Revision:

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