Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.installer / src / main / packaging / gvspkg @ 42775

History | View | Annotate | Download (58.9 KB)

1
#!/usr/bin/python
2
# -*- coding: utf-8 -*-
3
#
4
import sys
5
import os
6
import os.path
7
import fnmatch
8
import shutil
9
import zipfile
10
import stat
11
import getopt
12
from os.path import dirname
13
import shutil
14
from os import system
15
import ConfigParser
16
import StringIO
17
import re
18
import urllib2
19
import time
20

    
21
DEBUG = False
22
DEBUG = False
23
VERBOSE = False
24
SEARCH_VERSIONS = list()
25

    
26
#LINUX_EXEC_EXTENSION=".run" # antes ".bin"
27

    
28
class Platform:
29
  def __init__(self,os,arch,exe):
30
    self.os = os
31
    self.arch = arch
32
    self.exe_extension = exe
33
  
34
  def getOS():
35
    return self.os
36
  
37
  def getArch():
38
    return self.arch
39
  
40
  def getExeExtension():
41
    return self.exe_extension
42

    
43
platforms = ( 
44
  Platform("lin","x86",".run"),
45
  Platform("lin","x86_64",".run"),
46
  Platform("win","x86",".exe"),
47
  Platform("win","x86_64",".exe")
48
)
49

    
50

    
51
def log(msg):
52
  f=open("/tmp/gvspkg.log","a")
53
  f.write(time.ctime())
54
  f.write(": ")
55
  f.write(msg)
56
  f.write("\n")
57
  f.close()
58

    
59
def message(msg):
60
    if VERBOSE:
61
        print msg
62
        sys.stdout.flush()
63
    log(msg)
64

    
65
def msgerror(msg, err=None):
66
    print "ERROR: ", msg
67
    log("ERROR: "+msg)
68
    if err!=None :
69
      print "ERROR: ", str(err)
70
      sys.stdout.flush()
71
      log("ERROR: "+ str(err))
72

    
73

    
74
def msgwarn(msg):
75
    print "WARNING: ", msg
76
    sys.stdout.flush()
77
    log("WARNING: "+ msg)
78

    
79
def debug(msg):
80
    if DEBUG:
81
        print "DEBUG: ", msg
82
        sys.stdout.flush()
83
        log("DEBUG: "+ msg)
84

    
85
def acquire_file(name):
86
  files = list()
87
  folder = os.getcwd()
88
  while folder not in ( None, "", "/"):
89
    pathname = os.path.join(folder,name)
90
    if os.path.exists(pathname):
91
      files.append(pathname)
92
    folder = os.path.dirname(folder)
93
  return files
94

    
95
def get_gvspkg_bin_folder():
96
    files = list()
97
    if os.environ.get("HOME") != None :
98
        files.append(os.path.join(os.environ['HOME'],".gvspkg.bin"))
99
    files.extend( acquire_file(".gvspkg.bin") )
100
    files.extend( acquire_file("gvspkg.bin") )
101
    if len(files)<1 :
102
      return None
103
    debug( "gvspkg.bin = %s" % files[-1])
104
    return files[-1]
105

    
106
def search_GVSPKG_ROOT():
107
  f = get_gvspkg_bin_folder()
108
  if f==None:
109
    return None
110
  return os.path.dirname(f)
111

    
112
RWALL = stat.S_IWOTH | stat.S_IROTH | stat.S_IWUSR | stat.S_IRUSR | stat.S_IWGRP | stat.S_IRGRP
113
RWXALL = RWALL | stat.S_IXUSR | stat.S_IXOTH | stat.S_IXGRP
114

    
115
VERSION = os.path.basename(os.getcwd())
116
GVSPKG_ROOT = search_GVSPKG_ROOT()
117

    
118
def getVersion():
119
    return VERSION
120

    
121
def getSearchVersions():
122
    vers = list();
123
    vers.extend(SEARCH_VERSIONS)
124
    vers.append(VERSION)
125
    return vers
126

    
127
def getPackagesRoot():
128
    return GVSPKG_ROOT
129

    
130
def getPool():
131
    return getPackagesRoot() + "/pool"
132

    
133
def getWeb():
134
    return getPackagesRoot() + "/web"
135

    
136
def getDist():
137
    return getPackagesRoot() + "/dists/" +getVersion()
138

    
139
def findfiles(root,filename):
140
    result=list()
141
    for wroot, dirs, files in os.walk(root):
142
        for f in files :
143
            if fnmatch.fnmatch(f,filename):
144
                result.append(wroot+"/"+f)
145
    result.sort()
146
    return result
147

    
148
def mychmod(filename, perms):
149
    try:
150
        os.chmod(filename,perms)
151
    except Exception, ex:
152
        msgwarn("Can't change permissions of file '%s', error %s" % (filename, str(ex)))
153

    
154
def makedirs(path):
155
    if not os.path.isdir(path) :
156
      os.makedirs(path)
157

    
158
class Command:
159

    
160
    def __init__(self, args):
161
        self.args = args
162
        self.defaultoptions = None
163

    
164
    def load_options(self,filename):
165
        debug("loading option from %s" % filename)
166
        if not os.path.isfile(filename):
167
            debug("filename %s not found" % filename)
168
            return
169
        f=file(filename,"r")
170
        for line in f.readlines():
171
            line = line.strip()
172
            if line=="" or line.startswith("#"):
173
                continue
174
            if line[-1] == "\n":
175
                line = line[:-1]
176
            n = line.find("=")
177
            if n<0 :
178
                continue
179
            cmd = line[:n]
180
            args = line[n+1:].strip()
181

    
182
            if args != "":
183
              self.defaultoptions[cmd] = self.defaultoptions.get(cmd,[]) +  args.split(" ")
184
            debug("add options: %s=%r" % (cmd, args.split(" ")))
185

    
186
        f.close()
187

    
188
    def load_default_options(self):
189
        if self.defaultoptions != None:
190
            return
191
        self.defaultoptions = dict()
192
        options = list();
193
        if GVSPKG_ROOT != None:
194
          rootoptions = os.path.join(GVSPKG_ROOT,"gvspkg.bin/options")
195
        else:
196
          rootoptions = None
197
        if rootoptions != None and os.path.isfile(rootoptions):
198
            options.append(rootoptions)
199
        else:
200
            options.append("~/.gvspkg.bin/options")
201
        options.extend(acquire_file(".gvspkg.options"))
202
        options.extend(acquire_file("gvspkg.options"))
203
        for optionfile in options:
204
          self.load_options(optionfile)
205

    
206
    def getArgs(self,name):
207
        self.load_default_options()
208
        l = list()
209
        cmd = self.defaultoptions.get(name,None)
210
        if cmd != None:
211
          l.extend(cmd)
212
        l.extend(self.args[1:])
213
        return l
214

    
215
def isDigit(s):
216
    if len(s)>1:
217
        s=s[0]
218
    return s in ("0","1","2","3","4","5","6","7","8","9")
219

    
220

    
221

    
222
class PackageInfo(str):
223
    def __init__(self, filename):
224
        self._ini = None
225
        self.filename = filename[:-7]
226
        self.type = filename[-6:]
227
        s = os.path.basename(self.filename)
228
        s = s.split("-")
229
        #print "## PackageInfo ", repr(s)
230
        self.gvsig = s[0] + "-" + s[1]
231
        self.gvsig_version = s[2]
232
        self.code = s[3]
233
        try:
234
  # gvSIG-desktop-1.12.0-com.iver.cit.gvsig.cad-1.12.0-opencadtools-1418-final-all-all-j1_6.gvspkg
235
  #    0 -  1    -  2   -          3           -  4   - 5          -  6 - 7   - 8 - 9 - 10
236
  # gvSIG-desktop-1.12.0-com.iver.cit.gvsig.cad-1.12.0-1418-final-all-all-j1_6.gvspkg
237
  #    0 -  1    -  2   -          3           -  4   - 5  -  6  - 7 - 8 - 9
238

    
239
            if isDigit(s[5]) :
240
                self.version = s[4]
241
                self.build = s[5]
242
                self.status = s[6]
243
                self.os = s[7]
244
                self.arch = s[8]
245
            else:
246
                self.version = s[4] + "-" + s[5]
247
                self.build = s[6]
248
                self.status = s[7]
249
                self.os = s[8]
250
                self.arch = s[9]
251

    
252
        except Exception:
253
            self.build = "0"
254
            self.status = "unknow"
255
            self.os = "all"
256
            self.arch = "all"
257
        try:
258
            self.build = int(self.build)
259
        except:
260
            pass
261

    
262
    def getCode(self):
263
        return self.code
264

    
265
    def getOS(self):
266
        return self.os
267

    
268
    def getArch(self):
269
        return self.arch
270

    
271
    def getKey(self):
272
        return self.code+"-"+self.os+"-"+self.arch
273

    
274
    def getFullName(self):
275
        return os.path.basename(self.filename)
276

    
277
    def getFullVersion(self):
278
        try:
279
          r = re.compile("([0-9]+)[.]([0-9]+)[.]([0-9]+)-([a-zA-Z0-0]+)$")
280
          m = r.match(self.version)
281
          if m == None:
282
            clasificador="ZZZZZZZZ"
283
            r = re.compile("([0-9]+)[.]([0-9]+)[.]([0-9]+)$")
284
            m = r.match(self.version)
285
          else:
286
            clasificador=m.group(4)
287
          v1=int(m.group(1))
288
          v2=int(m.group(2))
289
          v3=int(m.group(3))
290
          return "%06d.%06d.%06d-%s-%06d" % (v1,v2,v3,clasificador,self.build)
291
        except:
292
          if "-" in self.version :
293
            return "%s-%06d" %(self.version,self.build)
294
          else:
295
            return "%s-ZZZZZZZZ-%06d" %(self.version,self.build)
296

    
297
    def getFilename(self):
298
        return self.filename + "." + self.type
299

    
300
    def hasPki(self):
301
        return os.path.isfile( self.getPkiFilename() )
302

    
303
    def getPkiFilename(self):
304
        return self.filename + ".gvspki"
305

    
306
    def hasPkg(self):
307
        return os.path.isfile( self.getPkgFilename() )
308

    
309
    def getPkgFilename(self):
310
        return self.filename + ".gvspkg"
311

    
312
    def getIniOption(self, name, default=None):
313
      section = "general"
314
      ini = self.getIni()
315
      if ini.has_option(section, name):
316
        x = ini.get(section, name)
317
        x = x.replace("\\:", ":")
318
        return x
319
      return default
320

    
321
    def getDescription(self):
322
      return self.getIniOption("description")
323

    
324
    def getCategories(self):
325
      return self.getIniOption("categories")
326

    
327
    def getName(self):
328
      return self.getIniOption("name")
329

    
330
    def getOwner(self):
331
      ini = self.getIni()
332
      if ini.has_option("general","owner"):
333
        return ini.get("general","owner")
334
      return None
335

    
336
    def getUrl(self):
337
      ini = self.getIni()
338
      if ini.has_option("general","download-url"):
339
        return ini.get("general","download-url")
340
      return None
341

    
342
    def getSourceUrl(self):
343
      ini = self.getIni()
344
      if ini.has_option("general","source-url"):
345
        return ini.get("general","source-url")
346
      return None
347

    
348
    def getDependencies(self):
349
      ini = self.getIni()
350
      if ini.has_option("general","dependencies"):
351
        return ini.get("general","dependencies")
352
      return None
353

    
354
    def getType(self):
355
      ini = self.getIni()
356
      if ini.has_option("general","type"):
357
        return ini.get("general","type")
358
      return None
359

    
360
    def getOfficial(self):
361
      ini = self.getIni()
362
      if ini.has_option("general","official"):
363
        return ini.get("general","official")
364
      return None
365

    
366
    def getIni(self):
367
        if self._ini != None:
368
          return self._ini
369
        index_path = self.getPkiFilename()
370
        outputfolder="/tmp/gvspkg.%s" % os.getpid()
371
        os.mkdir(outputfolder)
372
        os.system('unzip -q %s -d %s' % (index_path,outputfolder))
373

    
374
        files = findfiles(outputfolder, "package.info")
375
        if len(files) != 1:
376
            msgerror("Can't locate package.info in pool '%s'." % (index_path))
377
            return None
378

    
379
        package_info = files[0]
380
        self._ini = ConfigParser.ConfigParser()
381
        f = file(package_info,"r")
382
        ss = f.read()
383
        self._ini.readfp(StringIO.StringIO("[general]\n"+ss))
384
        f.close()
385
        shutil.rmtree(outputfolder)
386
        return self._ini
387

    
388
    def __str__(self):
389
        return self.filename
390

    
391
    def __repr__(self):
392
        return "filename=%r:gvsig=%r:gvsig_version=%r:code=%r:version=%r:build=%r:status=%r" % (
393
                self.filename, self.gvsig, self.gvsig_version, self.code, self.version, self.build, self.status )
394

    
395
class IndexList(list):
396

    
397
    def load(self, fname):
398
        message( "Loading index list from '%s'." % fname)
399
        f=file(fname,"r")
400
        lines=f.readlines()
401
        f.close()
402
        for line in lines:
403
          if line[-1] == "\n":
404
            line = line[:-1]
405

    
406
          info = PackageInfo(line)
407
          self.append(info)
408

    
409
    def save(self,fname):
410
        message( "Saving index list from '%s'." % fname)
411
        f=file(fname,"w")
412
        for index in self:
413
          f.write("%s\n" % index.getFilename())
414
        f.close()
415
        mychmod(fname,RWALL)
416

    
417
    def build(self, pool, versions):
418
        message( "Creating index list for version '%s' from '%s'" % (versions, pool) )
419
        packages=dict()
420
        for root, dirs, files in os.walk(pool):
421
            for f in files :
422
                if f[-7:].lower()  in (".gvspki", ".gvspkg") :
423
                    fullpath = root+"/"+f
424
                    info = PackageInfo(fullpath)
425
                    if info.gvsig == "gvSIG-desktop" and info.gvsig_version in versions :
426
                        if packages.get(info.getKey()) == None:
427
                            debug( "build: add    " + repr(info))
428
                            packages[info.getKey()]=info
429
                        else:
430
                            oldinfo = packages[info.getKey()]
431
                            debug("build: %s %s %s" % ( info.getKey(), oldinfo.getFullVersion(),info.getFullVersion()))
432
                            if oldinfo.getFullVersion()<info.getFullVersion()  :
433
                                debug( "build: update "+ repr(oldinfo))
434
                                packages[info.getKey()]=info
435
                    else:
436
                        debug( "build: skip   "+ repr(info))
437
        self.extend(packages.values())
438
        self.sort()
439

    
440
def lsi(args):
441
    cmd = Command(args)
442
    try:
443
        opts, args = getopt.getopt(cmd.getArgs("lsi"), "l", ["long-format"])
444
    except getopt.GetoptError, err:
445
        # print help information and exit:
446
        print str(err) # will print something like "option -a not recognized"
447
        shorthelp(args)
448
        sys.exit(2)
449

    
450
    long_format=False
451
    for opt, arg in opts:
452
        if opt in ("-l", "--long-format"):
453
            long_format = True
454
        else:
455
            assert False, "unhandled option"
456

    
457
    indexes = IndexList()
458
    indexes.build(getPool(), getSearchVersions())
459

    
460
    for info in indexes:
461
        if info.hasPki():
462
            if long_format:
463
                print "["+os.path.basename(info.getPkiFilename())+"]"
464
                print "# ", info.getPkiFilename()
465
                show(["show", os.path.basename(info.getPkiFilename())])
466
            else:
467
                print info.getPkiFilename()
468

    
469

    
470
def installer_add(cmd,arg1,arg2):
471
    installer_add_use_zip(cmd,arg1,arg2)
472

    
473
def installer_add_use_zip(cmd,arg1,arg2):
474
    if cmd == "addjrelin":
475
      return
476

    
477
    if cmd == "addjrewin":
478
      return
479

    
480
    if cmd == "addpks":
481
       zip = zipfile.ZipFile(arg1,"a",zipfile.ZIP_STORED)
482
       zip.write(arg2,"package.gvspks")
483
       zip.close()
484

    
485
def installer_add_use_installkit(cmd,arg1,arg2):
486
    folder = "%s/gvspkg.bin" % GVSPKG_ROOT
487

    
488
    cmd = "%s/installkit %s/main.tcl %s %s %s" % (
489
        "/mnt/data0/public-files/gvsig-desktop/gvspkg.bin",
490
        folder,
491
        cmd,
492
        arg1,
493
        arg2
494
    )
495
    system(cmd)
496

    
497
def mkinstall(args):
498
    cmd = Command(args)
499
    try:
500
        opts, args = getopt.getopt(cmd.getArgs("mkinstall"), "N:lL:wW:", ["addjrewin", "addjrelin", "jrelin=", "jrewin=", "distribution-name="])
501
    except getopt.GetoptError, err:
502
        # print help information and exit:
503
        print str(err) # will print something like "option -a not recognized"
504
        shorthelp(args)
505
        sys.exit(2)
506

    
507
    #print "opts = ",opts
508
    #print "args = ",args
509
    addjrelin=False
510
    addjrewin=False
511
    jrelin=None
512
    jrewin=None
513
    distribution_name = "custom"
514
    for opt, arg in opts:
515
        if opt in ("-L", "--jrelin"):
516
            jrelin = arg
517
        elif opt in ("-W", "--jrewin"):
518
            jrewin = arg
519
        elif opt in ("-l", "--addjrelin"):
520
            addjrelin = True
521
        elif opt in ("-w", "--addjrewin"):
522
            addjrewin = True
523
        elif opt in ("-N", "--distrinution-name"):
524
            distribution_name = arg
525
        else:
526
            assert False, "unhandled option"
527

    
528

    
529
    if len(args) != 2 :
530
        shorthelp(args)
531
        sys.exit(4)
532

    
533
    bin_name = args[0]
534
    gvspks_name = args[1]
535
    custom_name = bin_name.replace("online", distribution_name)
536

    
537
    if not "online" in bin_name :
538
        print "gvspkg mkinstall: binary file name must contain 'online'"
539
        sys.exit(3)
540

    
541
    if addjrelin and addjrewin :
542
        print "gvspkg mkinstall: only one of addjrelin or addjrewin is allowed."
543
        sys.exit(4)
544

    
545
    message("Creating %s..." % custom_name)
546
    shutil.copyfile(bin_name, custom_name)
547
    mychmod(custom_name,RWALL)
548
    message("Adding %s..." % gvspks_name)
549
    installer_add("addpks", custom_name, gvspks_name)
550

    
551
    """
552
    if addjrelin:
553
        withjre_name = bin_name.replace("online", distribution_name+"-withjre")
554
        message("Creating %s..." % withjre_name)
555
        shutil.copyfile(custom_name, withjre_name)
556
        mychmod(withjre_name,RWALL)
557
        message("Adding %s..." % jrelin)
558
        installer_add("addjrelin", withjre_name, jrelin)
559

    
560

    
561
    if addjrewin:
562
        withjre_name = bin_name.replace("online", distribution_name+"-withjre")
563
        message("Creating %s..." % withjre_name)
564
        shutil.copyfile(custom_name, withjre_name)
565
        mychmod(withjre_name,RWALL)
566
        message("Adding %s..." % jrewin)
567
        installer_add("addjrewin", withjre_name, jrewin)
568
    """
569

    
570
def mks(args):
571
    cmd = Command(args)
572
    try:
573
        opts, args = getopt.getopt(cmd.getArgs("mks"), "ixscI:", ["index-only","include-default-selection", "clear-list", "exclude=", "excludepki=", "excludepkg=", "include="])
574
    except getopt.GetoptError, err:
575
        # print help information and exit:
576
        print str(err) # will print something like "option -a not recognized"
577
        shorthelp(args)
578
        sys.exit(2)
579

    
580
    default_selection = None
581
    index_only = False
582
    clear_list=False
583
    includes=list()
584
    excludes_pki=list()
585
    excludes_pkg=list()
586
    for opt, arg in opts:
587
        if opt in ("-c", "--clear-list"):
588
            clear_list = True
589
        elif opt in ("-s", "--include-default-selection"):
590
            default_selection = "defaultPackages"
591
        elif opt in ("-x", "--exclude"):
592
            excludes_pki.append(arg)
593
            excludes_pkg.append(arg)
594
        elif opt in ( "--excludepki"):
595
            excludes_pki.append(arg)
596
        elif opt in ( "--excludepkg"):
597
            excludes_pkg.append(arg)
598
        elif opt in ( "--include", "-I"):
599
            if not os.path.isabs(arg) :
600
              arg = os.path.join(getPool(), arg)
601
            if arg.endswith(".*"):
602
              includes.append(PackageInfo(arg[:-2]+".gvspkg"))
603
              includes.append(PackageInfo(arg[:-2]+".gvspki"))
604
            else:
605
              includes.append(PackageInfo(arg))
606
        elif opt in ("-i", "--index-only"):
607
            index_only = True
608
        else:
609
            assert False, "unhandled option %r" % opt
610

    
611
    if default_selection!=None and  not os.path.isfile(default_selection) :
612
        msgwarn("No se ha encontrado el fichero %r. la opcion -s/--include-default-selection sera ignorada." % default_selection)
613
        default_selection = None
614

    
615

    
616
    indexes = IndexList()
617

    
618
    packages_txt = getDist() +"/packages.txt"
619
    packages_gvspki = getDist() +"/packages.gvspki"
620

    
621
    message( "Creating 'packages.gvspki' for version '%s'" % getVersion() + "...")
622
    if not os.path.exists(getDist()):
623
        msgerror("Can't locate version folder '%s'." % getDist())
624
        sys.exit(3)
625

    
626
    if os.path.exists(packages_txt) and not clear_list:
627
        indexes.load(packages_txt)
628
    else:
629
        indexes.build(getPool(), getSearchVersions())
630
        indexes.save(packages_txt)
631

    
632
    for pkg in includes:
633
      indexes.append(pkg)
634

    
635
    # El indice de paquetes lleva los paquetes para todas las plataformas y sistemas
636
    # ya que al conectarnos a el desde el administrador de complementos ya
637
    # se encarga la aplicacion de seleccionar los correspondientes a la plataforma
638
    # sobre la que esta rodando gvSIG.
639
    message( "Writing 'packages.gvspki' to '%s'" % packages_gvspki )
640
    set = zipfile.ZipFile(packages_gvspki,"w",zipfile.ZIP_STORED)
641
    for info in indexes:
642
        if not ( info.code in excludes_pki or info.getFullName() in excludes_pki ):
643
            debug("Add package '%s'" % info.getPkiFilename())
644
            try:
645
                if info.hasPki() :
646
                    set.write(info.getPkiFilename(), os.path.basename(info.getPkiFilename()))
647
            except Exception, ex:
648
                msgerror("Can't add index '%s', error %s" % (info, str(ex)))
649
        else:
650
            debug("Exclude package '%s'" % info.getFullName())
651
    if default_selection != None :
652
        set.write(default_selection,default_selection)
653
    set.close()
654
    mychmod(packages_gvspki,RWALL)
655

    
656
    md5sum(packages_gvspki,packages_gvspki+".md5")
657
    mychmod(packages_gvspki+".md5",RWALL)
658

    
659
    if not index_only :
660
      for platform in platforms:
661
        packages_gvspks = getDist() +"/packages-"+platform.getOS()+"-"+platform.getArch()+".gvspks"
662
        message( "Writing 'packages-"+platform.getOS()+"-"+platform.getArch()+".gvspks' to '%s'" % packages_gvspks )
663
        set = zipfile.ZipFile(packages_gvspks,"w",zipfile.ZIP_STORED)
664
        for info in indexes:
665
            if not ( info.code in excludes_pkg or info.getFullName() in excludes_pkg ):
666
                try:
667
                    if info.hasPkg():
668
                      if info.getOS() in ("all", platform.getOS()) :
669
                        if info.getArch() in ("all", platform.getArch()) :
670
                          set.write(info.getPkgFilename(), os.path.basename(info.getPkgFilename()))
671
                except Exception, ex:
672
                    msgerror("Can't add package '%s', error %s" % (index, str(ex)))
673
            else:
674
                debug("Exclude package '%s'" % info.getFullName())
675
        if default_selection != None :
676
            set.write(default_selection,default_selection)
677
        set.close()
678
        mychmod(packages_gvspks,RWALL)
679

    
680
        md5sum(packages_gvspks,packages_gvspks+".md5")
681
        mychmod(packages_gvspks+".md5",RWALL)
682

    
683
    message( "Createds package indexes.\n")
684

    
685
def mkmirror(args):
686
    cmd = Command(args)
687
    try:
688
        opts, args = getopt.getopt(cmd.getArgs("mkmirrot"), "b:", [ "build="])
689
    except getopt.GetoptError, err:
690
        # print help information and exit:
691
        print str(err) # will print something like "option -a not recognized"
692
        shorthelp(args)
693
        sys.exit(2)
694

    
695
    build = None
696
    for opt, arg in opts:
697
        if opt in ("-b", "--build"):
698
            build = arg
699
        else:
700
            assert False, "unhandled option %r" % opt
701

    
702
    if build == None:
703
        msgerror("Build number required.")
704
        sys.exit(3)
705
    domkmirror( getPackagesRoot(),getVersion(),build)
706

    
707
def linkfile(src,dst):
708
  if os.path.lexists(dst):
709
    os.remove(dst)
710
  os.symlink(src,dst)
711
  if os.path.lexists(src+".md5") :
712
    if os.path.lexists(dst+".md5"):
713
      os.remove(dst+".md5")
714
    os.symlink(src+".md5",dst+".md5")
715

    
716
def domkmirror(root_src, version, build):
717
  join = os.path.join
718

    
719
  build = str(build)
720
  root_target = join(root_src,"mirrors",version+"-"+build,"gvsig-desktop")
721
  build_src = join(root_src,"dists",version,"builds",build)
722
  build_target = join(root_target,"dists",version,"builds",build)
723
  pool_src = join(root_src,"pool")
724
  pool_target = join(root_target,"pool")
725

    
726
  makedirs(root_target)
727
  makedirs(build_target)
728
  makedirs(pool_target)
729
  files = os.listdir(build_src)
730
  linkfile(join(build_src,"packages.gvspki"), join(root_target,"dists",version,"packages.gvspki"))
731
  for f in files:
732
    f_src = join(build_src,f)
733
    f_target = join(build_target,f)
734
    if os.path.isfile(f_src):
735
      linkfile(f_src,f_target)
736

    
737
  z = zipfile.ZipFile(join(build_src,"packages.gvspki"))
738
  pkgs = z.namelist()
739
  for pkgname in pkgs:
740
    if pkgname!='defaultPackages':
741
      pkg = PackageInfo(pkgname)
742
      makedirs(join(root_target,"pool",pkg.getCode()))
743
      src = join(root_src,"pool",pkg.getCode(),pkg.getPkgFilename())
744
      target = join(root_target,"pool",pkg.getCode(),pkg.getPkgFilename())
745
      linkfile(src,target)
746
  cmd = "cd %s ; find . ! -type d >%s/files.lst" % (root_target, build_target)
747
  os.system(cmd)
748

    
749
def mkhtml(args):
750
    def getCode(info):
751
      return info.code
752

    
753

    
754
    cmd = Command(args)
755
    try:
756
        opts, args = getopt.getopt(cmd.getArgs("mkhtml"), "xsc", ["clear-list", "exclude=", "excludepki=", "excludepkg=", "include="])
757
    except getopt.GetoptError, err:
758
        # print help information and exit:
759
        print str(err) # will print something like "option -a not recognized"
760
        shorthelp(args)
761
        sys.exit(2)
762

    
763
    index_only = False
764
    clear_list=False
765
    includes=list()
766
    excludes_pki=list()
767
    excludes_pkg=list()
768
    for opt, arg in opts:
769
        if opt in ("-c", "--clear-list"):
770
            clear_list = True
771
        elif opt in ("-x", "--exclude"):
772
            excludes_pki.append(arg)
773
            excludes_pkg.append(arg)
774
        elif opt in ( "--excludepki"):
775
            excludes_pki.append(arg)
776
        elif opt in ( "--excludepkg"):
777
            excludes_pkg.append(arg)
778
        elif opt in ( "--include", "-I"):
779
            includes.append(PackageInfo(arg))
780
        else:
781
            assert False, "unhandled option %r" % opt
782

    
783
    message("Creating html pages...")
784
    indexes = IndexList()
785

    
786
    packages_txt = getDist() +"/packages.txt"
787

    
788
    if os.path.exists(packages_txt) and not clear_list:
789
        indexes.load(packages_txt)
790
    else:
791
        indexes.build(getPool(), getSearchVersions())
792
        indexes.save(packages_txt)
793

    
794
    for pkg in includes:
795
      indexes.append(pkg)
796

    
797
    allpackages = list()
798
    basepath = getWeb()
799
    for info in indexes:
800
        if not ( info.code in excludes_pki or info.getFullName() in excludes_pki ):
801
            try:
802
                if info.hasPki() :
803
                    mkpkihtml(basepath, info)
804
                    allpackages.append(info)
805
            except Exception, ex:
806
                msgerror("Can't create html '%s', error %s" % (info, str(ex)))
807

    
808
    html = '''
809
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
810
<html xmlns="http://www.w3.org/1999/xhtml">
811
<head>
812
  <meta http-equiv="Content-Type" content= "text/html; charset=us-ascii" />
813
      <title>"%s" package list</title>'''% getVersion() # Title
814

    
815
    html += '''
816
<!-- estilos para las tablas -->
817
  <style type="text/css" title="currentStyle">
818
    @import "css/demo_table.css";
819
    @import "css/thickbox.css";
820
    #pkglist{
821
        width:100%;
822
        clear:both;
823
        font-family:Arial,Helvetica,sans-serif;
824
    }
825
    #pkgdetails{
826
        width:600px !important;
827
        clear:both;
828
    }
829
    #pkgdetails table th{
830
        text-algin:right;
831
    }
832
  </style>
833
</head>'''
834

    
835
    html += '''
836
<body>
837
  <h1>%s package list</h1>
838
  <table id="pkglist" summary="%s package list" width="100%%" >
839
    <thead>
840
    <tr>
841
      <td>Package name</td>
842
      <td>Version</td>
843
      <td>O.S.</td>
844
      <td>Official</td>
845
      <td>Type</td>
846
      <td>Owner</td>
847
    </tr>
848
    </thead>
849
    <tbody>'''%(getVersion(),getVersion())
850

    
851
    # sort allpackages
852
    for item in sorted(allpackages, key=getCode):
853
      html += '''\n    <tr>
854
      <td><a class="thickbox" href="%s">%s</a></td>
855
      <td>%s</td>
856
      <td>%s</td>
857
      <td>%s</td>
858
      <td>%s</td>
859
      <td>%s</td>
860
    </tr>\n'''%(
861
  "../../../web/" + item.getFullName() + ".html?height=400&width=600",
862
        item.getName(),
863
  item.version,
864
  item.os,
865
  item.getOfficial(),
866
  item.getType(),
867
  item.getOwner()
868
      )
869
    html += """ </tbody>\n </table>
870
<!--javascript para la visualizaci�n de la tabla y carga din�mica del contenido del enlace -->
871
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js" type="text/javascript"></script>
872
<script src="http://datatables.net/release-datatables/media/js/jquery.dataTables.js" type="text/javascript"></script>
873
<script type="text/javascript" src="js/thickbox-compressed.js"></script>
874

    
875
<!-- inicializaci�n de la tabla con cosas chachis -->
876
<script type="text/javascript">
877
  $(document).ready(function() {
878
      $('#pkglist').dataTable( {
879
      "bPaginate": false,
880
      "bLengthChange": true,
881
      "bFilter": true,
882
      "bSort": true,
883
      "bInfo": true,
884
      "bAutoWidth": true
885
    });
886
 } );
887
</script>
888
</body>
889
</html>"""
890

    
891
    # generate index.html
892
    try:
893
      f=file(getDist()+"/web/index.html","w")
894
      f.write(html)
895
      f.close()
896
    except Exception, ex:
897
      raise ex
898

    
899
    message("html pages createds.\n")
900

    
901

    
902
def mkpkihtml(basepath, info):
903
  html='''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
904
<html xmlns="http://www.w3.org/1999/xhtml">
905
<head>
906
  <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
907
  <title>%s</title>
908
  <!-- estilos para las tablas -->
909
  <style type="text/css" title="currentStyle">
910
    @import "../dists/%s/web/css/demo_table.css";
911
    #pkgdetails{
912
      width:600px;
913
      clear:both;
914
    }
915
    #pkgdetails table th{
916
        text-algin:right;
917
    }
918
  </style>
919
</head>
920
<body>\n'''%(info.getIniOption("name"), getVersion())
921
  html += '  <table id="pkgdetails" summary=%s >\n'%info.getIniOption("name")
922
  html += '    <thead>\n  <tr>\n  <th>%s </th>\n  <td>%s</td>\n  </tr>\n  </thead>\n'%("Name", info.getIniOption("name"))
923
  html += '    <tbody><tr><th>%s </th><td>%s</td></tr>\n'%("Code", info.code)
924
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Version", info.version)
925
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("State", info.getIniOption("state"))
926
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Build", info.build)
927
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Owner", info.getOwner())
928

    
929
  #url = info.getUrl()
930
  url = info.getIniOption("download-url")
931
  if url != None:
932
    html += '    <tr><th valing="top">Downloads</th><td><a href ="%s">Binaries</a></td></tr>\n'%(url)
933
  else:
934
    html += '    <tr><th valing="top">Downloads</th><td>Binaries</td></tr>\n'
935

    
936
  sourceUrl = info.getSourceUrl()
937

    
938
  if sourceUrl != None:
939
    html += '    <tr><td></td><td><a href ="%s">Sources</a></td></tr>\n'%(sourceUrl)
940
  else:
941
    html += "    <tr><td></td><td>Sources</td></tr>\n"
942

    
943
  if info.getDependencies() == None:
944
    html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Dependencies", "")
945
  else:
946
    html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Dependencies", info.getDependencies().replace("\:",":"))
947
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Type", info.getType())
948
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Official", info.getOfficial())
949
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("O.S.", info.getOS())
950
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Architecture", info.getArch())
951
  html += '    <tr><th valing="top">%s </th><td>%s</td></tr>\n'%("Categories", info.getCategories())
952

    
953
  description = info.getDescription()
954
  if description == None:
955
    description = ""
956
  description = description.replace("\\n", "<br>")
957
  description = description.replace("\:",":")
958
  html += '    <tr valing="top"><th valing="top">%s </th><td>%s</td></tr>\n'%("Description", description)
959
  html += """  </tbody>\n</table>\n"""
960
  html += """
961
  <!-- javascript para la visualizaci�n de la tabla -->
962
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script>
963
  <script src="http://datatables.net/release-datatables/media/js/jquery.dataTables.js" type="text/javascript"></script>
964
  <!-- inicializaci�n de la tabla con cosas chachis -->
965
  <script type="text/javascript">
966
    $(document).ready(function() {
967
      $('#pkgdetails').dataTable( {
968
        "bPaginate": false,
969
        "bLengthChange": true,
970
        "bFilter": false,
971
        "bSort": false,
972
        "bInfo": false,
973
        "bAutoWidth": true
974
      });
975
    });
976
  </script>
977
  </body>\n</html>"""
978

    
979

    
980
  try:
981
    f = file(getWeb() + "/" + info.getFullName() + ".html","w")
982
    f.write(html)
983
    f.close()
984
  except Exception, ex:
985
    raise ex
986

    
987
def extract_make_portable(zfile, targetfolder):
988
  zf = zipfile.ZipFile(zfile)
989
  data = zf.read("tools/make-portable")
990
  f = open(os.path.join(targetfolder,"make-portable"),"wb")
991
  f.write(data)
992
  f.close()
993
  zf.close()
994

    
995
def prepare_portable(args):
996
    cmd = Command(args)
997
    try:
998
        opts, args = getopt.getopt(cmd.getArgs("prepare-portable"), "b:s:", [ "build=", "state=" ])
999
    except getopt.GetoptError, err:
1000
        # print help information and exit:
1001
        print str(err) # will print something like "option -a not recognized"
1002
        shorthelp(args)
1003
        sys.exit(2)
1004

    
1005
    build=None
1006
    state=None
1007
    for opt, arg in opts:
1008
        if opt in ("-b", "--build"):
1009
            build=arg
1010
        elif opt in ("-s", "--state"):
1011
            state=arg
1012
        else:
1013
            assert False, "unhandled option %r" % opt
1014

    
1015
    if build == None:
1016
      print "Requiered option --build not found."
1017
      shorthelp(args)
1018
      sys.exit(2)
1019

    
1020
    if state == None:
1021
      print "Requiered option --state not found."
1022
      shorthelp(args)
1023
      sys.exit(2)
1024

    
1025
    join = os.path.join
1026
    build_folder = join(getPackagesRoot(),"dists",getVersion(),"builds",build)
1027
    if not os.path.isdir(build_folder):
1028
      print "Can't access the build folder "+build_folder+"."
1029
      sys.exit(2)
1030

    
1031
    do_prepare_portable(build,state)
1032

    
1033
def do_prepare_portable(build,state):
1034
    join = os.path.join
1035
    build_folder = join(getPackagesRoot(),"dists",getVersion(),"builds",build)
1036
    portable_folder = join(build_folder,"misc","portable")
1037
    makedirs(portable_folder)
1038
    makedirs(join(portable_folder,"packages","custom"))
1039
    makedirs(join(portable_folder,"standard"))
1040
    makedirs(join(portable_folder,"patchs"))
1041
    f=open(join(portable_folder,"packages","excludes"),"w")
1042
    f.write("""EPSG_v6
1043
EPSG_v8_4
1044
EPSG_v8_5
1045
EPSG_v8_6
1046
org.gvsig.app.document.layout1.app.mainplugin
1047
org.gvsig.dyschromatopsia.app.extension
1048
org.gvsig.educa.portableview.app.editor
1049
org.gvsig.educa.portableview.app.viewer
1050
org.gvsig.projection.app.cresques
1051
org.gvsig.projection.app.proj4j
1052
org.gvsig.editing.app.mainplugin
1053
org.gvsig.downloader.app.mainplugin
1054
""")
1055
    f.close()
1056
    fname_base = "gvSIG-desktop-%s-%s-%s" % (getVersion(),build,state)
1057
    for platform in platforms :
1058
      linkfile(
1059
        join(build_folder,fname_base + "-" + platform.getOS() + "-" + platform.getArch() + "-online.zip"),
1060
        join(portable_folder,"standard",fname_base + "-" + platform.getOS() + "-" + platform.getArch() + "-online.zip")
1061
      )
1062
      linkfile(
1063
        join(build_folder,fname_base + "-" + cur_os + "-" + platform.getArch() + ".gvspks"),
1064
        join(portable_folder,"standard",fname_base + "-" + platform.getOS() + "-" + platform.getArch() + ".gvspks")
1065
      )
1066
    extract_make_portable(
1067
      join(build_folder,fname_base + "-lin-x86_64-online.zip"),
1068
      join(portable_folder)
1069
    )
1070
    mychmod(join(portable_folder,"make-portable"),RWXALL)
1071

    
1072
def zipfolder(source,target):
1073
  def zipdir(path, zip):
1074
      for root, dirs, files in os.walk(path):
1075
          for file in files:
1076
              zip.write(os.path.join(root, file))
1077
  zipf = zipfile.ZipFile(target, 'w')
1078
  zipdir(source, zipf)
1079
  zipf.close()
1080

    
1081
def removefile(filename):
1082
  if os.path.exists(filename):
1083
    os.remove(filename)
1084

    
1085
def mkportable(args):
1086
    cmd = Command(args)
1087
    try:
1088
        opts, args = getopt.getopt(cmd.getArgs("mkportable"), "b:s:", [ "build=", "state=" ])
1089
    except getopt.GetoptError, err:
1090
        # print help information and exit:
1091
        print str(err) # will print something like "option -a not recognized"
1092
        shorthelp(args)
1093
        sys.exit(2)
1094

    
1095
    build=None
1096
    state=None
1097
    for opt, arg in opts:
1098
        if opt in ("-b", "--build"):
1099
            build=arg
1100
        elif opt in ("-s", "--state"):
1101
            state=arg
1102
        else:
1103
            assert False, "unhandled option %r" % opt
1104

    
1105
    if build == None:
1106
      print "Requiered option --build not found."
1107
      shorthelp(args)
1108
      sys.exit(2)
1109

    
1110
    if state == None:
1111
      print "Requiered option --state not found."
1112
      shorthelp(args)
1113
      sys.exit(2)
1114

    
1115
    join = os.path.join
1116
    build_folder = join(getPackagesRoot(),"dists",getVersion(),"builds",build)
1117
    if not os.path.isdir(build_folder):
1118
      print "Can't access the build folder "+build_folder+"."
1119
      sys.exit(2)
1120

    
1121
    portable_folder = join(build_folder,"misc","portable")
1122
    if not os.path.isdir(portable_folder) :
1123
      do_prepare_portable(build,state)
1124
    os.system('cd %s ; ./make-portable' % (portable_folder))
1125
    
1126
    message("Removing previos portable zip files")
1127
    for platform in platforms :
1128
      removefile(join(build_folder,"gvSIG-desktop-%s-%s-%s-%s-%s.zip" %  (getVersion(),build,state,platform.getOS(),platform.getArch())))
1129

    
1130
    target_folder = join(getPackagesRoot(),"dists",getVersion(),"builds",build,"misc","portable","target")
1131
    for platform in platforms :
1132
      message("Moving zip gvSIG-desktop-%s-%s-%s-%s-%s.zip" % (getVersion(),build,state,platform.getOS(),platform.getArch()))
1133
      shutil.move(
1134
        join(portable_folder,"gvSIG-desktop-%s-%s-%s-%s-%s" % (getVersion(),build,state,platform.getOS(),platform.getArch())),
1135
        build_folder
1136
      )
1137
    #message("Remove temporary folders")
1138
    #shutil.rmtree(target_folder)
1139

    
1140
def mkdist(args):
1141
    cmd = Command(args)
1142
    try:
1143
        opts, args = getopt.getopt(cmd.getArgs("mkdist"), "b:s:", [ "build=", "state=", "distribution_name=" ])
1144
    except getopt.GetoptError, err:
1145
        # print help information and exit:
1146
        print str(err) # will print something like "option -a not recognized"
1147
        shorthelp(args)
1148
        sys.exit(2)
1149

    
1150
    build=None
1151
    state=None
1152
    distribution_name = "standard"
1153

    
1154
    for opt, arg in opts:
1155
        if opt in ("-b", "--build"):
1156
            build=arg
1157
        elif opt in ("-s", "--state"):
1158
            state=arg
1159
        elif opt in ("-N", "--distrinution-name"):
1160
            distribution_name = arg
1161
        else:
1162
            assert False, "unhandled option %r" % opt
1163

    
1164
    if build == None:
1165
      print "Requiered option --build not found."
1166
      shorthelp(args)
1167
      sys.exit(2)
1168

    
1169
    if state == None:
1170
      print "Requiered option --state not found."
1171
      shorthelp(args)
1172
      sys.exit(2)
1173

    
1174
    if not os.path.isdir("builds/"+build):
1175
      print "Can't access the build folder builds/"+build+"."
1176
      sys.exit(2)
1177

    
1178
    message( "Generating distribution for build "+ build + "...")
1179
    message("Recreating index of packages...")
1180
    executeCommand("mks", "-s", "-c")
1181

    
1182
    executeCommand("mkhtml" )
1183

    
1184
    gvspki_filename = "builds/"+build+"/packages.gvspki"
1185
    message( "Coping packages.gvspki to "+ gvspki_filename + "\n")
1186
    shutil.copyfile("packages.gvspki", gvspki_filename)
1187
    shutil.copyfile("packages.gvspki.md5", gvspki_filename +".md5")
1188

    
1189
    for platform in platforms:
1190
        message( "Creating installers for platform "+cur_os+"/"+cur_arch+"...")
1191
        gvspks_filename = "builds/"+build+"/gvSIG-desktop-" + VERSION + "-" + build+ "-" + state + "-"+platform.getOS()+"-"+platform.getArch()+".gvspks"
1192
        online_filename = "builds/"+build+"/gvSIG-desktop-" + VERSION + "-" + build+ "-" + state + "-"+platform.getOS()+"-"+platform.getArch() + "-online.jar"
1193

    
1194
        if not os.path.isfile(online_filename):
1195
          msgwarn("Can't access the online installable for "+platform.getOS()+"/"+platform.getArch() + " ("+online_filename+").")
1196
          continue
1197

    
1198
        message( "Coping packages-"+platform.getOS()+"-"+platform.getArch()+".gvspks to "+ gvspks_filename)
1199
        shutil.copyfile("packages-"+platform.getOS()+"-"+platform.getArch()+".gvspks", gvspks_filename)
1200
        shutil.copyfile("packages-"+platform.getOS()+"-"+platform.getArch()+".gvspks.md5", gvspks_filename +".md5")
1201

    
1202
        message( "Add execution permissions to online installables....")
1203
        mychmod(online_filename,RWXALL)
1204

    
1205
        md5sum(online_filename,online_filename+".md5")
1206
        mychmod(online_filename+".md5",RWALL)
1207

    
1208

    
1209
        executeCommand("mkinstall" , "--addjre"+platform.getOS(), online_filename, gvspks_filename)
1210

    
1211
        message( "Renaming files from custom to standard...")
1212
        target_filename = "builds/"+build+"/gvSIG-desktop-" + VERSION + "-" + build+ "-" + state + "-"+platform.getOS()+"-"+platform.getArch()+"-"+distribution_name + ".jar"
1213
        shutil.move(
1214
            "builds/"+build+"/gvSIG-desktop-" + VERSION + "-" + build+ "-" + state + "-"+platform.getOS()+"-"+platform.getArch() + "-custom.jar",
1215
            target_filename
1216
        )
1217
        mychmod(target_filename,RWXALL)
1218

    
1219
        md5sum(target_filename,target_filename+".md5")
1220
        mychmod(target_filename+".md5",RWALL)
1221

    
1222
        message( "Createds installers for platform "+platform.getOS()+"/"+platform.getArch()+"\n")
1223

    
1224
    message( "Coping html index to browse paqueges of the distro.")
1225
    shutil.rmtree("builds/"+build+"/web", ignore_errors=True)
1226
    shutil.copytree("web", "builds/"+build+"/web")
1227
    f = file("builds/"+build+"/web/index.html","r")
1228
    contents = f.read()
1229
    f.close()
1230
    contents = contents.replace("href=\"../../../web/gvSIG-desktop-", "href=\"../../../../../web/gvSIG-desktop-")
1231
    f = file("builds/"+build+"/web/index.html","w")
1232
    f.write(contents)
1233
    f.close()
1234

    
1235
    message( "\nCreation of distribution completed.\n")
1236

    
1237

    
1238

    
1239

    
1240
def show(args):
1241
    cmd = Command(args)
1242
    try:
1243
        opts, args = getopt.getopt(cmd.getArgs("show"), "S", [ "verify"])
1244
    except getopt.GetoptError, err:
1245
        # print help information and exit:
1246
        print str(err) # will print something like "option -a not recognized"
1247
        shorthelp(args)
1248
        sys.exit(2)
1249

    
1250
    eerify = False
1251
    for opt, arg in opts:
1252
        if opt in ("-V", "--verify"):
1253
            verify = True
1254
        else:
1255
            assert False, "unhandled option %r" % opt
1256

    
1257
    index_name=args[0]
1258
    message( "Show package.info from '%s'" % index_name)
1259
    files = findfiles(getPool(), index_name)
1260
    if len(files) != 1:
1261
        msgerror("Can't locate package '%s' in pool '%s'." % (index_name, getPool()))
1262
        return
1263
    index_path = files[0]
1264
    outputfolder="/tmp/gvspkg.%s" % os.getpid()
1265
    os.mkdir(outputfolder)
1266
    os.system('unzip -q %s -d %s' % (index_path,outputfolder))
1267

    
1268
    files = findfiles(outputfolder, "package.info")
1269
    if len(files) != 1:
1270
        msgerror("Can't locate package.info in pool '%s'." % (index_name))
1271
        return
1272

    
1273
    package_info = files[0]
1274
    f = file(package_info,"r")
1275
    s = f.read()
1276
    f.close()
1277
    print s
1278
    if verify:
1279
      verify_sign(package_info)
1280
    shutil.rmtree(outputfolder)
1281

    
1282
def editall(args):
1283
    cmd = Command(args)
1284
    try:
1285
        opts, args = getopt.getopt(cmd.getArgs("editall"), "Scx:I:r:", ["clear-list", "exclude=", "excludepki=", "excludepkg=", "include=", "replace=", "sign"])
1286
    except getopt.GetoptError, err:
1287
        # print help information and exit:
1288
        print str(err) # will print something like "option -a not recognized"
1289
        shorthelp(args)
1290
        sys.exit(2)
1291

    
1292
    index_only = False
1293
    clear_list=False
1294
    includes=list()
1295
    excludes_pki=list()
1296
    replaces = list()
1297
    excludes_pkg=list()
1298
    sign = False
1299
    interactive = True
1300
    for opt, arg in opts:
1301
        if opt in ("-c", "--clear-list"):
1302
            clear_list = True
1303
        elif opt in ("-x", "--exclude"):
1304
            excludes_pki.append(arg)
1305
            excludes_pkg.append(arg)
1306
        elif opt in ( "--excludepki"):
1307
            excludes_pki.append(arg)
1308
        elif opt in ( "--excludepkg"):
1309
            excludes_pkg.append(arg)
1310
        elif opt in ( "--include", "-I"):
1311
            includes.append(PackageInfo(arg))
1312
        elif opt in ("-r", "--replace"):
1313
            interactive = False
1314
            replaces.append(arg)
1315
        elif opt in ("-S", "--sign"):
1316
            sign = True
1317
        else:
1318
            assert False, "unhandled option %r" % opt
1319

    
1320
    indexes = IndexList()
1321

    
1322
    packages_txt = getDist() +"/packages.txt"
1323
    if os.path.exists(packages_txt) and not clear_list:
1324
        indexes.load(packages_txt)
1325
    else:
1326
        indexes.build(getPool(), getSearchVersions())
1327
        indexes.save(packages_txt)
1328

    
1329
    for pkg in includes:
1330
      indexes.append(pkg)
1331

    
1332
    allpackages = list()
1333
    for info in indexes:
1334
        if not ( info.code in excludes_pki or info.getFullName() in excludes_pki ):
1335
            try:
1336
                if info.hasPki() :
1337
                  print info.getPkiFilename()
1338
                  if interactive :
1339
                    edit_pkginfo_of_package(info.getPkiFilename(), edit_ui)
1340
                  elif len(replaces) < 1:
1341
                    edit_pkginfo_of_package(info.getPkiFilename(), edit_replace, replaces)
1342

    
1343
                  if sign:
1344
                    edit_pkginfo_of_package(info.getPkiFilename(), edit_sign)
1345

    
1346
            except Exception, ex:
1347
                msgerror("Can't add index '%s', error %s" % (info, str(ex)))
1348

    
1349
def edit(args):
1350
    cmd = Command(args)
1351
    try:
1352
        opts, args = getopt.getopt(cmd.getArgs("edit"), "Sr:", [ "replace=", "onlysign", "sign" ])
1353
    except getopt.GetoptError, err:
1354
        # print help information and exit:
1355
        print str(err) # will print something like "option -a not recognized"
1356
        shorthelp(args)
1357
        sys.exit(2)
1358

    
1359
    replaces = list()
1360
    interactive = True
1361
    sign = False
1362
    for opt, arg in opts:
1363
        if opt in ("-r", "--replace"):
1364
            interactive = False
1365
            replaces.append(arg)
1366
        elif opt in ("--onlysign"):
1367
            interactive = False
1368
            sign = True
1369
        elif opt in ("-S", "--sign"):
1370
            sign = True
1371
        else:
1372
            assert False, "unhandled option %r" % opt
1373

    
1374
    index_name=args[0]
1375
    message( "Show package.info from '%s'" % index_name)
1376
    files = findfiles(getPool(), index_name)
1377
    if len(files) != 1:
1378
        msgerror("Can't locate package '%s' in pool '%s'." % (index_name, getPool()))
1379
        return
1380
    index_path = files[0]
1381
    if interactive:
1382
      edit_pkginfo_of_package(index_path, edit_ui)
1383
    elif len(replaces) < 1:
1384
      edit_pkginfo_of_package(index_path, edit_replace, replaces)
1385

    
1386
    if sign:
1387
      edit_pkginfo_of_package(index_path, edit_sign)
1388

    
1389
def edit_ui(filename, args):
1390
      os.system('vi "%s"' % filename)
1391

    
1392
def edit_replace(filename, args):
1393
      replaces = args[0]
1394
      f = open(filename)
1395
      s = f.read()
1396
      f.close()
1397
      for replace in replaces:
1398
        x = replace.split(replace[0])
1399
        if len(x)==4:
1400
          s=re.sub(x[1],x[2],s)
1401
      f = open(filename,"w")
1402
      f.write(s)
1403
      f.close()
1404

    
1405
def edit_sign(filename, args):
1406
      os.system('java -cp "%s/commons-codec-1.6.jar:%s/org.gvsig.installer.lib.impl-1.0.1-SNAPSHOT.jar" org.gvsig.installer.lib.impl.utils.SignUtil sign %s' %  (
1407
        get_gvspkg_bin_folder(),
1408
        get_gvspkg_bin_folder(),
1409
        filename)
1410
      )
1411

    
1412
def verify_sign(filename):
1413
      os.system('java -cp "%s/commons-codec-1.6.jar:%s/org.gvsig.installer.lib.impl-1.0.1-SNAPSHOT.jar" org.gvsig.installer.lib.impl.utils.SignUtil verify %s' % (
1414
        get_gvspkg_bin_folder(),
1415
        get_gvspkg_bin_folder(),
1416
        filename)
1417
      )
1418

    
1419
def edit_pkginfo_of_package(pkg_path, operation, *args):
1420
    outputfolder="/tmp/gvspkg.%s" % os.getpid()
1421
    os.mkdir(outputfolder)
1422
    os.system('unzip -q %s -d %s' % (pkg_path,outputfolder))
1423

    
1424
    files = findfiles(outputfolder, "package.info")
1425
    if len(files) != 1:
1426
        msgerror("Can't locate package.info in pool '%s'." % (pkg_path))
1427
        return
1428

    
1429
    package_info = files[0]
1430
    code = package_info.split("/")[-2]
1431
    operation(package_info, args)
1432

    
1433
    # zip -Dr kk.zip org.gvsig.wfs
1434
    temp_index_name = "/tmp/packages.gvspki.%s" % os.getpid()
1435
    temp_index = zipfile.ZipFile(temp_index_name,"w",zipfile.ZIP_STORED)
1436
    temp_index.write(package_info, "%s/package.info" % (code))
1437
    temp_index.close()
1438
    shutil.rmtree(outputfolder)
1439
    os.remove(pkg_path)
1440
    shutil.move(temp_index_name,pkg_path)
1441

    
1442
def install(args):
1443
    cmd = Command(args)
1444
    try:
1445
        opts, args = getopt.getopt(cmd.getArgs("install"), "fS", [ "force","nohttps" ])
1446
    except getopt.GetoptError, err:
1447
        # print help information and exit:
1448
        print str(err) # will print something like "option -a not recognized"
1449
        shorthelp(args)
1450
        sys.exit(2)
1451

    
1452
    force = False
1453
    nohttps = False
1454
    for opt, arg in opts:
1455
        if opt in ("-f", "--force"):
1456
            force = True
1457
        if opt in ("-S", "--nohttps"):
1458
            nohttps = True
1459
        else:
1460
            assert False, "unhandled option %r" % opt
1461

    
1462
    url_pki = args[0]
1463
    if url_pki.startswith("https:") and nohttps :
1464
       url_pki = "http:" + url_pki[6:]
1465

    
1466
    message( "Download package index '%s'" % url_pki)
1467
    temppath_pki= os.path.join("/tmp",os.path.basename(url_pki))
1468
    if not downloadFile(url_pki,temppath_pki):
1469
      msgerror("Can't download index.")
1470
      msgerror("Can't install '%s'." % url_pki)
1471
      print # force a newline
1472
      return 1
1473
    pkg = PackageInfo(temppath_pki)
1474
    url_pkg = pkg.getUrl().replace("\\","")
1475
    if url_pkg[-7:] == ".gvspki" :
1476
      msgwarn("Suspicious download-url value. Ends with gvspki, expected gvspkg.")
1477
      msgwarn("download-url ='%s'." % url_pkg)
1478

    
1479
    if url_pkg.startswith("https:") and nohttps :
1480
       url_pkg = "http:" + url_pkg[6:]
1481

    
1482
    message( "Download package '%s'" % url_pkg)
1483
    temppath_pkg= os.path.join("/tmp",os.path.basename(url_pkg))
1484
    if not downloadFile(url_pkg,temppath_pkg):
1485
      msgerror("Can't download package from download-url ('%s')." % url_pkg)
1486
      msgerror("Can't install '%s'," % url_pki)
1487
      print # force a newline
1488
      return 1
1489
    folder = os.path.join(getPool(),pkg.getCode())
1490
    makedirs(folder)
1491
    pathname_pki = os.path.join(folder,os.path.basename(url_pki))
1492
    if not force and os.path.isfile(pathname_pki) :
1493
        msgwarn("The package index alreade exist in the pool. Use -f to forrce install.")
1494
        print # force a newline
1495
        return 1
1496
    pathname_pkg = os.path.join(folder,os.path.basename(url_pkg))
1497
    if  not force and os.path.isfile(pathname_pki) :
1498
        msgwarn("The package downloaded from download-url alredy exists in the pool. Use -f to force install.")
1499
        print # force a newline
1500
        return 1
1501
    message( "installing package '%s'" % os.path.basename(pathname_pki))
1502
    shutil.copyfile(temppath_pki, pathname_pki)
1503
    message( "installing package '%s'" % os.path.basename(pathname_pkg))
1504
    shutil.copyfile(temppath_pkg, pathname_pkg)
1505

    
1506
    md5sum(pathname_pki, pathname_pki+".md5")
1507
    md5sum(pathname_pkg, pathname_pkg+".md5")
1508

    
1509

    
1510
def md5sum(fin, fout):
1511
    message( "Calculating md5sum of %s..." % fin )
1512
    system("md5sum -b %s >%s" % (fin, fout) )
1513

    
1514
def downloadFile(url,path):
1515
  try:
1516
    fsrc = urllib2.urlopen(url)
1517
  except urllib2.HTTPError,e:
1518
    msgerror("Error abriendo url '%s'." % url, e)
1519
    return False
1520
  fdst = file(path,"wb")
1521
  shutil.copyfileobj(fsrc,fdst)
1522
  fdst.close()
1523
  fsrc.close()
1524
  return True
1525

    
1526
def shorthelp(args):
1527
    print """
1528
usage: gvspkg [OPTIONS] COMMANDS
1529
OPTIONS:
1530

    
1531
-h,--help       Muestra esta ayuda
1532
-v,--verbose    Activa el modo verbose
1533
-d,--debug      Activa el modo debug.
1534
--version ver   Fija la version con la que van a trabajar.
1535
-r,--package-root root    Fija la carpeta del raiz del sistema de paquetes
1536

    
1537
COMMANDS:
1538

    
1539
mkinstall [OPTIONS] install-file packages-file
1540
    -L, --jrelin=path
1541
    -W, --jrewin=path
1542
    -l, --addjrelin
1543
    -w, --addjrewin
1544
    -N, --distribution-name=name
1545

    
1546
lsi [OPTIONS]
1547
    -l, --long-format
1548

    
1549
mks [OPTIONS]
1550
     -c, --clear-list
1551
     --excludepkg pkgcode
1552
     --excludepki pkgcode
1553
     --exclude pkgcode
1554
     -s, --include-default-selection
1555
     -i, --index-only
1556
     -I full-path-to-package, --include full-path-to-package
1557

    
1558
mkdist [OPTIONS]
1559
     -s STATE, --state=STATE
1560
     -b BUILD, --build=BUILD
1561
     -N, --distribution-name=name
1562

    
1563
mkmirror [OPTIONS]
1564
     -b, --build buildnumber
1565

    
1566
mkhtml [OPTIONS]
1567
     -c, --clear-list
1568
     --excludepkg pkgcode
1569
     --excludepki pkgcode
1570
     --exclude pkgcode
1571

    
1572
show OPTIONS package-index
1573
    --verify, -V
1574

    
1575
edit [OPTIONS] package-index
1576
     --replace=@search@replace@
1577
     --onlysign
1578
     --sign, -S
1579

    
1580
editall [OPTIONS]
1581
     -c, --clear-list
1582
     --excludepkg pkgcode
1583
     --excludepki pkgcode
1584
     --exclude pkgcode
1585
     --replace=@search@replace@
1586
     --sign, -S
1587

    
1588
install [OPTIONS] url-to-pki
1589
     -f, --force
1590

    
1591
prepare-portable [OPTIONS]
1592
     -b, --build
1593
     -s, --state
1594

    
1595
mkportable [OPTIONS]
1596
     -b, --build
1597
     -s, --state
1598

    
1599
La version actual a utilizar es:
1600
  %s
1601

    
1602
El directorio root de la estructura de packetes actual es:
1603
  %s
1604
    """ % (VERSION, GVSPKG_ROOT)
1605

    
1606

    
1607
def help(args):
1608
    print """
1609
usage: gvspkg [OPTIONS] COMMANDS
1610

    
1611
OPTIONS:
1612

    
1613
-h|--help
1614
    Muestra esta ayuda
1615

    
1616
-v|--verbose
1617
    Activa el modo verbose
1618

    
1619
-d|--debug
1620
    Activa el modo debug. Se muestran mensajes que pueden ser
1621
    utilies de cara a depuracion.
1622

    
1623
--version version
1624
    Fija la version con la que van a trabajar los comandos indicados.
1625

    
1626
-r|--package-root package-root
1627
    Fija la carpeta en la que va a buscar el raiz del sistema de paquetes
1628
    con el que trabajar
1629

    
1630
COMMANDS:
1631

    
1632
mkinstall [OPTIONS] install-file packages-file
1633

    
1634
    OPTIONS:
1635

    
1636
    -L | --jrelin=path
1637

    
1638
    -W | --jrewin=path
1639

    
1640
    -l | --addjrelin
1641

    
1642
    -w | --addjrewin
1643

    
1644
    -N | --distribution-name=name
1645
      Nombre usado como sufijo del nuevo binario a generar. Por defecto si no se
1646
      indica valdra "custom".
1647

    
1648

    
1649
lsi [OPTIONS]
1650
    Lista los indices disponibles de la version
1651

    
1652
    OPTIONS:
1653

    
1654
    -l | --long-format
1655
        Muestra para cada paquete la informacion del package.info
1656

    
1657
mks [OPTIONS]
1658
     Crea el fichero packages.gvspki con los indices de la
1659
     version y packages.gvspkg con los paquetes.
1660

    
1661
     OPTIONS:
1662

    
1663
     -c | --clear-list
1664
        Elimina la lista de paquetes a utilizar recreandola a partir
1665
        de los paquetes del pool tomando el ultimo build de cada paquete.
1666

    
1667
     --excludepkg pkgcode
1668
        No incluye el paquete indicado en el fichero gvspkg a generar
1669

    
1670
     --excludepki pkgcode
1671
        No incluye el paquete indicado en el fichero gvspki a generar
1672

    
1673
     --exclude pkgcode
1674
        No incluye el paquete indicado en los ficheros gvspkg y gvspki a generar
1675

    
1676
     -s | --include-default-selection
1677
        Incluye el fichero "defaultPackages", que se debe encontrar en el
1678
        directorio corriente, con los nombres de paquetes a seleccionar
1679
        por defecto.
1680

    
1681
     -i | --index-only
1682
        No crea el fichero gvspks, solo crea el gvspki
1683

    
1684
     -I full-path-to-package | --include full-path-to-package
1685
        A�ade el paquete indicado a la lista de paquetes aunque no coincida para
1686
        la version de gvSIG con la que se esta trabajando.
1687

    
1688
mkdist [OPTIONS]
1689
     Crea los ficheros de la distribucion standard para el buil dindicado a partir de
1690
     la distribucion online y los paquetes que hayan en el pool para esta version.
1691
     Ejecuta un "mks" y un "mkhtml" automaticamente para preparar el conjunto de paquetes
1692
     a incluir en la distribucion, y una vez preparados ejecuta un "mkinsrall" por
1693
     S.O. (win y lin), renombrando los ficheros generados segun corresponda.
1694

    
1695
     OPTIONS:
1696
     -s STATE | --state=STATE
1697
        Indica el estado de la distribucion a generar, devel, alpha, ..., debe estar
1698
        deacuerdo con lo que diga el cihero online a usar como base.
1699

    
1700
     -b BUILD | --build=BUILD
1701
        Indica el numero de build de la destribucion a generar. Es usado para localizar
1702
        los ficheros en la carpeta builds de la distribucion y para saber donde debe
1703
        dejar los ficheros generados.
1704

    
1705
     -N | --distribution-name=name
1706
        Nombre usado como sufijo del nuevo binario a generar. Por defecto si no se
1707
        indica valdra "standard".
1708

    
1709

    
1710
mkmirror [OPTIONS]
1711

    
1712
  Prepara una carpeta para hacer un mirror de un build en concreto.
1713

    
1714
     OPTIONS:
1715

    
1716
     -b | --build buildnumber
1717
       Indica el numero de build del que se quiere hacer un mirror.
1718

    
1719
mkhtml [OPTIONS]
1720
     ????
1721

    
1722
     OPTIONS:
1723

    
1724
     -c | --clear-list
1725
        Elimina la lista de paquetes a utilizar recreandola a partir
1726
        de los paquetes del pool tomando el ultimo build de cada paquete.
1727

    
1728
     --excludepkg pkgcode
1729
        No incluye el paquete indicado en el fichero gvspkg a generar
1730

    
1731
     --excludepki pkgcode
1732
        No incluye el paquete indicado en el fichero gvspki a generar
1733

    
1734
     --exclude pkgcode
1735
        No incluye el paquete indicado en los ficheros gvspkg y gvspki a generar
1736

    
1737
show OPTIONS package-index
1738
    Muestra el package.info del indice indicado como parametro.
1739

    
1740
    OPTIONS
1741

    
1742
    --verify | -V
1743
      Comprueba la forma del packete.
1744

    
1745
edit [OPTIONS] package-index
1746
    Edita el package.info del indice indicado como parametro.
1747

    
1748
     OPTIONS:
1749

    
1750
     --replace=@search@replace@
1751
       Reemplaza en el package.info de cada paquete la cadena "search" por "replace"
1752
       todas las veces que aparezca. "@" puede ser cualquier caracter que no aparezca
1753
       en "search" y "replace".
1754
       Esta opcion puede indicarse tatas veces como reemplazos se deseen efectuar.
1755

    
1756
     --onlysign
1757
       firma el package.info sin editarlo de forma interactiva (no invoca al editor antes
1758
       de firmarlo).
1759

    
1760
     --sign | -S
1761
       Firma el package.info tras terminar la edicion (bach o interactiva)
1762

    
1763
editall [OPTIONS]
1764
    Edita todos los package.info
1765

    
1766
     OPTIONS:
1767

    
1768
     -c | --clear-list
1769
        Elimina la lista de paquetes a utilizar recreandola a partir
1770
        de los paquetes del pool tomando el ultimo build de cada paquete.
1771

    
1772
     --excludepkg pkgcode
1773
        No incluye el paquete indicado en el fichero gvspkg a generar
1774

    
1775
     --excludepki pkgcode
1776
        No incluye el paquete indicado en el fichero gvspki a generar
1777

    
1778
     --exclude pkgcode
1779
        No incluye el paquete indicado en los ficheros gvspkg y gvspki a generar
1780

    
1781
     --replace=@search@replace@
1782
       Reemplaza en el package.info de cada paquete la cadena "search" por "replace"
1783
       todas las veces que aparezca. "@" puede ser cualquier caracter que no aparezca
1784
       en "search" y "replace".
1785
       Esta opcion puede indicarse tatas veces como reemplazos se deseen efectuar.
1786

    
1787
      --sign | -S
1788
        Firma todos los paquetes que sean oficiales
1789

    
1790
install [OPTIONS] url-to-pki
1791
    descarga de la url indicada un fichero gvspki e instala este junto con su correspondiente
1792
    pkg en el pool local.
1793

    
1794
     OPTIONS:
1795

    
1796
     -f | --force
1797
       fuerza la sobreescritura de los ficheros en caso de que estos ya existan.
1798

    
1799
Si en la carpeta corriente encuentra un fichero gvspkg.options cargara los
1800
flags indicados ahi como flags por defecto para cada comando. El formato del
1801
fichero es:
1802
  main=OPCION-POR-DEFECTO
1803
  mks=OPCOPNES-POR-DEFECTO
1804
Donde main indica las opciones por defecto generales, independientes del comando
1805
a ejecutar. "mks" indica las opciones por defecto a usar en el comando "mks", y
1806
asi sucesivamente, indicando el nombre del comando seguido de un "=" y las opciones
1807
por defecto para ese comando.
1808

    
1809
Por defecto la version la obtiene del nombre de la carpeta
1810
corriente (%s). Las opciones indicadas en el fichero gvspkg.options tienen prioridad
1811
sobre este valor.
1812

    
1813
El directorio root de la estructura de packetes lo buscara en el
1814
sitio indicado por la variable de entorno GVPKG_ROOT, y si esta no
1815
esta establecida usara "%s". Las opciones indicadas en el fichero gvspkg.options
1816
tienen prioridad sobre este valor.
1817

    
1818
    """ % (VERSION, GVSPKG_ROOT)
1819

    
1820
def executeCommand(*args):
1821
    command = "shorthelp"
1822
    if len(args)>0:
1823
        command=args[0]
1824

    
1825
    r=1
1826
    if command=="lsi" :
1827
        r=lsi(args)
1828
    elif command == "mks":
1829
        r=mks(args)
1830
    elif command == "edit":
1831
        r=edit(args)
1832
    elif command == "editall":
1833
        r=editall(args)
1834
    elif command == "show":
1835
        r=show(args)
1836
    elif command == "mkhtml":
1837
        r=mkhtml(args)
1838
    elif command == "mkinstall":
1839
        r=mkinstall(args)
1840
    elif command == "install":
1841
        r=install(args)
1842
    elif command == "mkdist":
1843
        r=mkdist(args)
1844
    elif command == "mkmirror":
1845
        r=mkmirror(args)
1846
    elif command == "mkportable":
1847
        r=mkportable(args)
1848
    elif command == "prepare-portable":
1849
        r=prepare_portable(args)
1850
    elif command == "help":
1851
        r=help(args)
1852
    else:
1853
        r=shorthelp(args)
1854
    return r
1855

    
1856
def main():
1857
    global DEBUG
1858
    global VERSION
1859
    global VERBOSE
1860
    global GVSPKG_ROOT
1861
    global SEARCH_VERSIONS
1862

    
1863
    cmd = Command(sys.argv)
1864
    try:
1865
        opts, args = getopt.getopt(cmd.getArgs("main"), "dhvr:", ["debug", "verbose", "version=", "package-root=","help","search_versions="])
1866
    except getopt.GetoptError, err:
1867
        # print help information and exit:
1868
        print str(err) # will print something like "option -a not recognized"
1869
        shorthelp(None)
1870
        sys.exit(2)
1871

    
1872
    for opt, arg in opts:
1873
        if opt in ("-h", "--help"):
1874
            shorthelp(args)
1875
            sys.exit()
1876
        elif opt in ("-d", "--debug"):
1877
            DEBUG = True
1878
        elif opt in ("-v", "--verbose"):
1879
            VERBOSE = True
1880
        elif opt in ("--version"):
1881
            VERSION = arg
1882
        elif opt in ("--search_versions"):
1883
            SEARCH_VERSIONS.append(arg)
1884
        elif opt in ("-r", "--package-root"):
1885
            GVSPKG_ROOT = arg
1886
        else:
1887
            assert False, "unhandled option"
1888
    #
1889
    debug("DEBUG=%s" % DEBUG)
1890
    debug("VERSION=%s" % VERSION)
1891
    debug("GVSPKG_ROOT=%s" % GVSPKG_ROOT)
1892
    if GVSPKG_ROOT == None:
1893
      shorthelp(None)
1894
    else:
1895
      r=executeCommand(*args)
1896
      sys.exit(r)
1897

    
1898
main()