annotate Lib/msilib/__init__.py @ 54294:dba767bc3155 legacy-trunk

remove mention of old ctypes version
author Benjamin Peterson <benjamin@python.org>
date Sat, 23 May 2009 20:59:09 +0000
parents 8cda615ef22b
children b43398ea549d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
36845
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
1 # -*- coding: iso-8859-1 -*-
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
2 # Copyright (C) 2005 Martin v. Löwis
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
3 # Licensed to PSF under a Contributor Agreement.
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
4 from _msi import *
48921
8cda615ef22b Issue #3732: Backported r53335 to supress deprecation warning.
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents: 39031
diff changeset
5 import os, string, re
36845
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
6
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
7 Win64=0
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
8
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
9 # Partially taken from Wine
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
10 datasizemask= 0x00ff
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
11 type_valid= 0x0100
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
12 type_localizable= 0x0200
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
13
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
14 typemask= 0x0c00
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
15 type_long= 0x0000
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
16 type_short= 0x0400
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
17 type_string= 0x0c00
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
18 type_binary= 0x0800
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
19
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
20 type_nullable= 0x1000
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
21 type_key= 0x2000
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
22 # XXX temporary, localizable?
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
23 knownbits = datasizemask | type_valid | type_localizable | \
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
24 typemask | type_nullable | type_key
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
25
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
26 class Table:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
27 def __init__(self, name):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
28 self.name = name
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
29 self.fields = []
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
30
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
31 def add_field(self, index, name, type):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
32 self.fields.append((index,name,type))
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
33
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
34 def sql(self):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
35 fields = []
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
36 keys = []
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
37 self.fields.sort()
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
38 fields = [None]*len(self.fields)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
39 for index, name, type in self.fields:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
40 index -= 1
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
41 unk = type & ~knownbits
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
42 if unk:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
43 print "%s.%s unknown bits %x" % (self.name, name, unk)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
44 size = type & datasizemask
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
45 dtype = type & typemask
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
46 if dtype == type_string:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
47 if size:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
48 tname="CHAR(%d)" % size
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
49 else:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
50 tname="CHAR"
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
51 elif dtype == type_short:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
52 assert size==2
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
53 tname = "SHORT"
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
54 elif dtype == type_long:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
55 assert size==4
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
56 tname="LONG"
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
57 elif dtype == type_binary:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
58 assert size==0
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
59 tname="OBJECT"
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
60 else:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
61 tname="unknown"
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
62 print "%s.%sunknown integer type %d" % (self.name, name, size)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
63 if type & type_nullable:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
64 flags = ""
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
65 else:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
66 flags = " NOT NULL"
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
67 if type & type_localizable:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
68 flags += " LOCALIZABLE"
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
69 fields[index] = "`%s` %s%s" % (name, tname, flags)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
70 if type & type_key:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
71 keys.append("`%s`" % name)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
72 fields = ", ".join(fields)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
73 keys = ", ".join(keys)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
74 return "CREATE TABLE %s (%s PRIMARY KEY %s)" % (self.name, fields, keys)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
75
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
76 def create(self, db):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
77 v = db.OpenView(self.sql())
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
78 v.Execute(None)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
79 v.Close()
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
80
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
81 class _Unspecified:pass
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
82 def change_sequence(seq, action, seqno=_Unspecified, cond = _Unspecified):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
83 "Change the sequence number of an action in a sequence list"
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
84 for i in range(len(seq)):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
85 if seq[i][0] == action:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
86 if cond is _Unspecified:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
87 cond = seq[i][1]
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
88 if seqno is _Unspecified:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
89 seqno = seq[i][2]
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
90 seq[i] = (action, cond, seqno)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
91 return
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
92 raise ValueError, "Action not found in sequence"
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
93
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
94 def add_data(db, table, values):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
95 v = db.OpenView("SELECT * FROM `%s`" % table)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
96 count = v.GetColumnInfo(MSICOLINFO_NAMES).GetFieldCount()
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
97 r = CreateRecord(count)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
98 for value in values:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
99 assert len(value) == count, value
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
100 for i in range(count):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
101 field = value[i]
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
102 if isinstance(field, (int, long)):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
103 r.SetInteger(i+1,field)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
104 elif isinstance(field, basestring):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
105 r.SetString(i+1,field)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
106 elif field is None:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
107 pass
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
108 elif isinstance(field, Binary):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
109 r.SetStream(i+1, field.name)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
110 else:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
111 raise TypeError, "Unsupported type %s" % field.__class__.__name__
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
112 try:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
113 v.Modify(MSIMODIFY_INSERT, r)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
114 except Exception, e:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
115 raise MSIError("Could not insert "+repr(values)+" into "+table)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
116
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
117 r.ClearData()
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
118 v.Close()
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
119
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
120
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
121 def add_stream(db, name, path):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
122 v = db.OpenView("INSERT INTO _Streams (Name, Data) VALUES ('%s', ?)" % name)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
123 r = CreateRecord(1)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
124 r.SetStream(1, path)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
125 v.Execute(r)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
126 v.Close()
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
127
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
128 def init_database(name, schema,
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
129 ProductName, ProductCode, ProductVersion,
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
130 Manufacturer):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
131 try:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
132 os.unlink(name)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
133 except OSError:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
134 pass
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
135 ProductCode = ProductCode.upper()
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
136 # Create the database
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
137 db = OpenDatabase(name, MSIDBOPEN_CREATE)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
138 # Create the tables
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
139 for t in schema.tables:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
140 t.create(db)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
141 # Fill the validation table
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
142 add_data(db, "_Validation", schema._Validation_records)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
143 # Initialize the summary information, allowing atmost 20 properties
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
144 si = db.GetSummaryInformation(20)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
145 si.SetProperty(PID_TITLE, "Installation Database")
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
146 si.SetProperty(PID_SUBJECT, ProductName)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
147 si.SetProperty(PID_AUTHOR, Manufacturer)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
148 if Win64:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
149 si.SetProperty(PID_TEMPLATE, "Intel64;1033")
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
150 else:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
151 si.SetProperty(PID_TEMPLATE, "Intel;1033")
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
152 si.SetProperty(PID_REVNUMBER, gen_uuid())
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
153 si.SetProperty(PID_WORDCOUNT, 2) # long file names, compressed, original media
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
154 si.SetProperty(PID_PAGECOUNT, 200)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
155 si.SetProperty(PID_APPNAME, "Python MSI Library")
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
156 # XXX more properties
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
157 si.Persist()
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
158 add_data(db, "Property", [
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
159 ("ProductName", ProductName),
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
160 ("ProductCode", ProductCode),
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
161 ("ProductVersion", ProductVersion),
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
162 ("Manufacturer", Manufacturer),
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
163 ("ProductLanguage", "1033")])
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
164 db.Commit()
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
165 return db
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
166
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
167 def add_tables(db, module):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
168 for table in module.tables:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
169 add_data(db, table, getattr(module, table))
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
170
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
171 def make_id(str):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
172 #str = str.replace(".", "_") # colons are allowed
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
173 str = str.replace(" ", "_")
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
174 str = str.replace("-", "_")
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
175 if str[0] in string.digits:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
176 str = "_"+str
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
177 assert re.match("^[A-Za-z_][A-Za-z0-9_.]*$", str), "FILE"+str
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
178 return str
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
179
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
180 def gen_uuid():
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
181 return "{"+UuidCreate().upper()+"}"
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
182
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
183 class CAB:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
184 def __init__(self, name):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
185 self.name = name
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
186 self.files = []
48921
8cda615ef22b Issue #3732: Backported r53335 to supress deprecation warning.
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents: 39031
diff changeset
187 self.filenames = set()
36845
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
188 self.index = 0
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
189
39031
8fefa99e87c0 Properly generate logical file ids. Fixes #1515998.
Martin v. Löwis <martin@v.loewis.de>
parents: 38072
diff changeset
190 def gen_id(self, file):
36845
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
191 logical = _logical = make_id(file)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
192 pos = 1
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
193 while logical in self.filenames:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
194 logical = "%s.%d" % (_logical, pos)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
195 pos += 1
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
196 self.filenames.add(logical)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
197 return logical
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
198
39031
8fefa99e87c0 Properly generate logical file ids. Fixes #1515998.
Martin v. Löwis <martin@v.loewis.de>
parents: 38072
diff changeset
199 def append(self, full, file, logical):
36845
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
200 if os.path.isdir(full):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
201 return
39031
8fefa99e87c0 Properly generate logical file ids. Fixes #1515998.
Martin v. Löwis <martin@v.loewis.de>
parents: 38072
diff changeset
202 if not logical:
8fefa99e87c0 Properly generate logical file ids. Fixes #1515998.
Martin v. Löwis <martin@v.loewis.de>
parents: 38072
diff changeset
203 logical = self.gen_id(file)
36845
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
204 self.index += 1
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
205 self.files.append((full, logical))
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
206 return self.index, logical
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
207
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
208 def commit(self, db):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
209 from tempfile import mktemp
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
210 filename = mktemp()
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
211 FCICreate(filename, self.files)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
212 add_data(db, "Media",
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
213 [(1, self.index, None, "#"+self.name, None, None)])
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
214 add_stream(db, self.name, filename)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
215 os.unlink(filename)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
216 db.Commit()
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
217
48921
8cda615ef22b Issue #3732: Backported r53335 to supress deprecation warning.
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents: 39031
diff changeset
218 _directories = set()
36845
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
219 class Directory:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
220 def __init__(self, db, cab, basedir, physical, _logical, default, componentflags=None):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
221 """Create a new directory in the Directory table. There is a current component
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
222 at each point in time for the directory, which is either explicitly created
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
223 through start_component, or implicitly when files are added for the first
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
224 time. Files are added into the current component, and into the cab file.
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
225 To create a directory, a base directory object needs to be specified (can be
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
226 None), the path to the physical directory, and a logical directory name.
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
227 Default specifies the DefaultDir slot in the directory table. componentflags
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
228 specifies the default flags that new components get."""
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
229 index = 1
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
230 _logical = make_id(_logical)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
231 logical = _logical
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
232 while logical in _directories:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
233 logical = "%s%d" % (_logical, index)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
234 index += 1
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
235 _directories.add(logical)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
236 self.db = db
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
237 self.cab = cab
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
238 self.basedir = basedir
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
239 self.physical = physical
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
240 self.logical = logical
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
241 self.component = None
48921
8cda615ef22b Issue #3732: Backported r53335 to supress deprecation warning.
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents: 39031
diff changeset
242 self.short_names = set()
8cda615ef22b Issue #3732: Backported r53335 to supress deprecation warning.
Hirokazu Yamamoto <ocean-city@m2.ccsnet.ne.jp>
parents: 39031
diff changeset
243 self.ids = set()
36845
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
244 self.keyfiles = {}
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
245 self.componentflags = componentflags
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
246 if basedir:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
247 self.absolute = os.path.join(basedir.absolute, physical)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
248 blogical = basedir.logical
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
249 else:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
250 self.absolute = physical
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
251 blogical = None
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
252 add_data(db, "Directory", [(logical, blogical, default)])
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
253
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
254 def start_component(self, component = None, feature = None, flags = None, keyfile = None, uuid=None):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
255 """Add an entry to the Component table, and make this component the current for this
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
256 directory. If no component name is given, the directory name is used. If no feature
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
257 is given, the current feature is used. If no flags are given, the directory's default
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
258 flags are used. If no keyfile is given, the KeyPath is left null in the Component
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
259 table."""
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
260 if flags is None:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
261 flags = self.componentflags
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
262 if uuid is None:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
263 uuid = gen_uuid()
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
264 else:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
265 uuid = uuid.upper()
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
266 if component is None:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
267 component = self.logical
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
268 self.component = component
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
269 if Win64:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
270 flags |= 256
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
271 if keyfile:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
272 keyid = self.cab.gen_id(self.absolute, keyfile)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
273 self.keyfiles[keyfile] = keyid
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
274 else:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
275 keyid = None
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
276 add_data(self.db, "Component",
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
277 [(component, uuid, self.logical, flags, None, keyid)])
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
278 if feature is None:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
279 feature = current_feature
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
280 add_data(self.db, "FeatureComponents",
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
281 [(feature.id, component)])
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
282
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
283 def make_short(self, file):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
284 parts = file.split(".")
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
285 if len(parts)>1:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
286 suffix = parts[-1].upper()
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
287 else:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
288 suffix = None
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
289 prefix = parts[0].upper()
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
290 if len(prefix) <= 8 and (not suffix or len(suffix)<=3):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
291 if suffix:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
292 file = prefix+"."+suffix
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
293 else:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
294 file = prefix
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
295 assert file not in self.short_names
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
296 else:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
297 prefix = prefix[:6]
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
298 if suffix:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
299 suffix = suffix[:3]
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
300 pos = 1
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
301 while 1:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
302 if suffix:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
303 file = "%s~%d.%s" % (prefix, pos, suffix)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
304 else:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
305 file = "%s~%d" % (prefix, pos)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
306 if file not in self.short_names: break
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
307 pos += 1
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
308 assert pos < 10000
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
309 if pos in (10, 100, 1000):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
310 prefix = prefix[:-1]
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
311 self.short_names.add(file)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
312 assert not re.search(r'[\?|><:/*"+,;=\[\]]', file) # restrictions on short names
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
313 return file
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
314
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
315 def add_file(self, file, src=None, version=None, language=None):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
316 """Add a file to the current component of the directory, starting a new one
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
317 one if there is no current component. By default, the file name in the source
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
318 and the file table will be identical. If the src file is specified, it is
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
319 interpreted relative to the current directory. Optionally, a version and a
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
320 language can be specified for the entry in the File table."""
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
321 if not self.component:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
322 self.start_component(self.logical, current_feature, 0)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
323 if not src:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
324 # Allow relative paths for file if src is not specified
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
325 src = file
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
326 file = os.path.basename(file)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
327 absolute = os.path.join(self.absolute, src)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
328 assert not re.search(r'[\?|><:/*]"', file) # restrictions on long names
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
329 if self.keyfiles.has_key(file):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
330 logical = self.keyfiles[file]
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
331 else:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
332 logical = None
39031
8fefa99e87c0 Properly generate logical file ids. Fixes #1515998.
Martin v. Löwis <martin@v.loewis.de>
parents: 38072
diff changeset
333 sequence, logical = self.cab.append(absolute, file, logical)
36845
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
334 assert logical not in self.ids
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
335 self.ids.add(logical)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
336 short = self.make_short(file)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
337 full = "%s|%s" % (short, file)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
338 filesize = os.stat(absolute).st_size
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
339 # constants.msidbFileAttributesVital
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
340 # Compressed omitted, since it is the database default
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
341 # could add r/o, system, hidden
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
342 attributes = 512
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
343 add_data(self.db, "File",
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
344 [(logical, self.component, full, filesize, version,
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
345 language, attributes, sequence)])
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
346 #if not version:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
347 # # Add hash if the file is not versioned
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
348 # filehash = FileHash(absolute, 0)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
349 # add_data(self.db, "MsiFileHash",
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
350 # [(logical, 0, filehash.IntegerData(1),
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
351 # filehash.IntegerData(2), filehash.IntegerData(3),
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
352 # filehash.IntegerData(4))])
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
353 # Automatically remove .pyc/.pyo files on uninstall (2)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
354 # XXX: adding so many RemoveFile entries makes installer unbelievably
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
355 # slow. So instead, we have to use wildcard remove entries
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
356 if file.endswith(".py"):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
357 add_data(self.db, "RemoveFile",
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
358 [(logical+"c", self.component, "%sC|%sc" % (short, file),
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
359 self.logical, 2),
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
360 (logical+"o", self.component, "%sO|%so" % (short, file),
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
361 self.logical, 2)])
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
362 return logical
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
363
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
364 def glob(self, pattern, exclude = None):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
365 """Add a list of files to the current component as specified in the
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
366 glob pattern. Individual files can be excluded in the exclude list."""
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
367 files = glob.glob1(self.absolute, pattern)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
368 for f in files:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
369 if exclude and f in exclude: continue
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
370 self.add_file(f)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
371 return files
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
372
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
373 def remove_pyc(self):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
374 "Remove .pyc/.pyo files on uninstall"
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
375 add_data(self.db, "RemoveFile",
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
376 [(self.component+"c", self.component, "*.pyc", self.logical, 2),
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
377 (self.component+"o", self.component, "*.pyo", self.logical, 2)])
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
378
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
379 class Binary:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
380 def __init__(self, fname):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
381 self.name = fname
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
382 def __repr__(self):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
383 return 'msilib.Binary(os.path.join(dirname,"%s"))' % self.name
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
384
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
385 class Feature:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
386 def __init__(self, db, id, title, desc, display, level = 1,
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
387 parent=None, directory = None, attributes=0):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
388 self.id = id
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
389 if parent:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
390 parent = parent.id
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
391 add_data(db, "Feature",
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
392 [(id, parent, title, desc, display,
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
393 level, directory, attributes)])
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
394 def set_current(self):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
395 global current_feature
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
396 current_feature = self
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
397
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
398 class Control:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
399 def __init__(self, dlg, name):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
400 self.dlg = dlg
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
401 self.name = name
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
402
38072
ee98ecf05773 Rename parameters to match the documentation (which
Martin v. Löwis <martin@v.loewis.de>
parents: 36845
diff changeset
403 def event(self, event, argument, condition = "1", ordering = None):
36845
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
404 add_data(self.dlg.db, "ControlEvent",
38072
ee98ecf05773 Rename parameters to match the documentation (which
Martin v. Löwis <martin@v.loewis.de>
parents: 36845
diff changeset
405 [(self.dlg.name, self.name, event, argument,
ee98ecf05773 Rename parameters to match the documentation (which
Martin v. Löwis <martin@v.loewis.de>
parents: 36845
diff changeset
406 condition, ordering)])
36845
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
407
39031
8fefa99e87c0 Properly generate logical file ids. Fixes #1515998.
Martin v. Löwis <martin@v.loewis.de>
parents: 38072
diff changeset
408 def mapping(self, event, attribute):
36845
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
409 add_data(self.dlg.db, "EventMapping",
38072
ee98ecf05773 Rename parameters to match the documentation (which
Martin v. Löwis <martin@v.loewis.de>
parents: 36845
diff changeset
410 [(self.dlg.name, self.name, event, attribute)])
36845
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
411
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
412 def condition(self, action, condition):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
413 add_data(self.dlg.db, "ControlCondition",
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
414 [(self.dlg.name, self.name, action, condition)])
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
415
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
416 class RadioButtonGroup(Control):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
417 def __init__(self, dlg, name, property):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
418 self.dlg = dlg
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
419 self.name = name
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
420 self.property = property
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
421 self.index = 1
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
422
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
423 def add(self, name, x, y, w, h, text, value = None):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
424 if value is None:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
425 value = name
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
426 add_data(self.dlg.db, "RadioButton",
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
427 [(self.property, self.index, value,
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
428 x, y, w, h, text, None)])
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
429 self.index += 1
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
430
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
431 class Dialog:
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
432 def __init__(self, db, name, x, y, w, h, attr, title, first, default, cancel):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
433 self.db = db
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
434 self.name = name
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
435 self.x, self.y, self.w, self.h = x,y,w,h
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
436 add_data(db, "Dialog", [(name, x,y,w,h,attr,title,first,default,cancel)])
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
437
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
438 def control(self, name, type, x, y, w, h, attr, prop, text, next, help):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
439 add_data(self.db, "Control",
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
440 [(self.name, name, type, x, y, w, h, attr, prop, text, next, help)])
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
441 return Control(self, name)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
442
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
443 def text(self, name, x, y, w, h, attr, text):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
444 return self.control(name, "Text", x, y, w, h, attr, None,
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
445 text, None, None)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
446
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
447 def bitmap(self, name, x, y, w, h, text):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
448 return self.control(name, "Bitmap", x, y, w, h, 1, None, text, None, None)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
449
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
450 def line(self, name, x, y, w, h):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
451 return self.control(name, "Line", x, y, w, h, 1, None, None, None, None)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
452
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
453 def pushbutton(self, name, x, y, w, h, attr, text, next):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
454 return self.control(name, "PushButton", x, y, w, h, attr, None, text, next, None)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
455
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
456 def radiogroup(self, name, x, y, w, h, attr, prop, text, next):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
457 add_data(self.db, "Control",
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
458 [(self.name, name, "RadioButtonGroup",
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
459 x, y, w, h, attr, prop, text, next, None)])
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
460 return RadioButtonGroup(self, name, prop)
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
461
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
462 def checkbox(self, name, x, y, w, h, attr, prop, text, next):
391f74c9c263 Import bdist_msi
Martin v. Löwis <martin@v.loewis.de>
parents:
diff changeset
463 return self.control(name, "CheckBox", x, y, w, h, attr, prop, text, next, None)