~ntt-pf-lab/nova/monkey_patch_notification

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/scripts/tkunzip.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""Post-install GUI to compile to pyc and unpack twisted doco"""
 
2
 
 
3
from __future__ import generators
 
4
 
 
5
import sys
 
6
import zipfile
 
7
import py_compile
 
8
 
 
9
# we're going to ignore failures to import tkinter and fall back
 
10
# to using the console if the required dll is not found
 
11
 
 
12
# Scary kludge to work around tk84.dll bug: 
 
13
# https://sourceforge.net/tracker/index.php?func=detail&aid=814654&group_id=5470&atid=105470
 
14
# Without which(): you get a windows missing-dll popup message
 
15
from twisted.python.procutils import which
 
16
tkdll='tk84.dll'
 
17
if which(tkdll) or which('DLLs/%s' % tkdll):
 
18
    try:
 
19
        import Tkinter
 
20
        from Tkinter import *
 
21
        from twisted.internet import tksupport
 
22
    except ImportError:
 
23
        pass
 
24
 
 
25
# twisted
 
26
from twisted.internet import reactor, defer
 
27
from twisted.python import failure, log, zipstream, util, usage, log
 
28
# local
 
29
import os.path
 
30
 
 
31
class ProgressBar:
 
32
    def __init__(self, master=None, orientation="horizontal",
 
33
                 min=0, max=100, width=100, height=18,
 
34
                 doLabel=1, appearance="sunken",
 
35
                 fillColor="blue", background="gray",
 
36
                 labelColor="yellow", labelFont="Arial",
 
37
                 labelText="", labelFormat="%d%%",
 
38
                 value=0, bd=2):
 
39
        # preserve various values
 
40
        self.master=master
 
41
        self.orientation=orientation
 
42
        self.min=min
 
43
        self.max=max
 
44
        self.width=width
 
45
        self.height=height
 
46
        self.doLabel=doLabel
 
47
        self.fillColor=fillColor
 
48
        self.labelFont= labelFont
 
49
        self.labelColor=labelColor
 
50
        self.background=background
 
51
        self.labelText=labelText
 
52
        self.labelFormat=labelFormat
 
53
        self.value=value
 
54
        self.frame=Frame(master, relief=appearance, bd=bd)
 
55
        self.canvas=Canvas(self.frame, height=height, width=width, bd=0,
 
56
                           highlightthickness=0, background=background)
 
57
        self.scale=self.canvas.create_rectangle(0, 0, width, height,
 
58
                                                fill=fillColor)
 
59
        self.label=self.canvas.create_text(self.canvas.winfo_reqwidth() / 2,
 
60
                                           height / 2, text=labelText,
 
61
                                           anchor="c", fill=labelColor,
 
62
                                           font=self.labelFont)
 
63
        self.update()
 
64
        self.canvas.pack(side='top', fill='x', expand='no')
 
65
 
 
66
    def pack(self, *args, **kwargs):
 
67
        self.frame.pack(*args, **kwargs)
 
68
    
 
69
    def updateProgress(self, newValue, newMax=None):
 
70
        if newMax:
 
71
            self.max = newMax
 
72
        self.value = newValue
 
73
        self.update()
 
74
 
 
75
    def update(self):
 
76
        # Trim the values to be between min and max
 
77
        value=self.value
 
78
        if value > self.max:
 
79
            value = self.max
 
80
        if value < self.min:
 
81
            value = self.min
 
82
        # Adjust the rectangle
 
83
        if self.orientation == "horizontal":
 
84
            self.canvas.coords(self.scale, 0, 0,
 
85
              float(value) / self.max * self.width, self.height)
 
86
        else:
 
87
            self.canvas.coords(self.scale, 0,
 
88
                               self.height - (float(value) / 
 
89
                                              self.max*self.height),
 
90
                               self.width, self.height)
 
91
        # Now update the colors
 
92
        self.canvas.itemconfig(self.scale, fill=self.fillColor)
 
93
        self.canvas.itemconfig(self.label, fill=self.labelColor)
 
94
        # And update the label
 
95
        if self.doLabel:
 
96
            if value:
 
97
                if value >= 0:
 
98
                    pvalue = int((float(value) / float(self.max)) * 
 
99
                                   100.0)
 
100
                else:
 
101
                    pvalue = 0
 
102
                self.canvas.itemconfig(self.label, text=self.labelFormat
 
103
                                         % pvalue)
 
104
            else:
 
105
                self.canvas.itemconfig(self.label, text='')
 
106
        else:
 
107
            self.canvas.itemconfig(self.label, text=self.labelFormat %
 
108
                                   self.labelText)
 
109
        self.canvas.update_idletasks()
 
110
 
 
111
 
 
112
class Progressor:
 
113
    """A base class to make it simple to hook a progress bar up to a process.
 
114
    """
 
115
    def __init__(self, title, *args, **kwargs):
 
116
        self.title=title
 
117
        self.stopping=0
 
118
        self.bar=None
 
119
        self.iterator=None
 
120
        self.remaining=1000
 
121
 
 
122
    def setBar(self, bar, max):
 
123
        self.bar=bar
 
124
        bar.updateProgress(0, max)
 
125
        return self
 
126
 
 
127
    def setIterator(self, iterator):
 
128
        self.iterator=iterator
 
129
        return self
 
130
    
 
131
    def updateBar(self, deferred):
 
132
        b=self.bar
 
133
        try:
 
134
            b.updateProgress(b.max - self.remaining)
 
135
        except TclError:
 
136
            self.stopping=1
 
137
        except:
 
138
            deferred.errback(failure.Failure())
 
139
 
 
140
    def processAll(self, root):
 
141
        assert self.bar and self.iterator, "must setBar and setIterator"
 
142
        self.root=root
 
143
        root.title(self.title)
 
144
        d=defer.Deferred()
 
145
        d.addErrback(log.err)
 
146
        reactor.callLater(0.1, self.processOne, d)
 
147
        return d
 
148
 
 
149
    def processOne(self, deferred):
 
150
        if self.stopping:
 
151
            deferred.callback(self.root)
 
152
            return
 
153
        
 
154
        try:
 
155
            self.remaining=self.iterator.next()
 
156
        except StopIteration:
 
157
            self.stopping=1            
 
158
        except:
 
159
            deferred.errback(failure.Failure())
 
160
        
 
161
        if self.remaining%10==0:
 
162
            reactor.callLater(0, self.updateBar, deferred)
 
163
        if self.remaining%100==0:
 
164
            log.msg(self.remaining)
 
165
        reactor.callLater(0, self.processOne, deferred)
 
166
 
 
167
def compiler(path):
 
168
    """A generator for compiling files to .pyc"""
 
169
    def justlist(arg, directory, names):
 
170
        pynames=[os.path.join(directory, n) for n in names
 
171
                 if n.endswith('.py')]
 
172
        arg.extend(pynames)
 
173
    all=[]
 
174
    os.path.walk(path, justlist, all)
 
175
 
 
176
    remaining=len(all)
 
177
    i=zip(all, range(remaining-1, -1, -1))
 
178
    for f, remaining in i:
 
179
        py_compile.compile(f)
 
180
        yield remaining
 
181
 
 
182
class TkunzipOptions(usage.Options):
 
183
    optParameters=[["zipfile", "z", "", "a zipfile"],
 
184
                   ["ziptargetdir", "t", ".", "where to extract zipfile"],
 
185
                   ["compiledir", "c", "", "a directory to compile"],
 
186
                   ]
 
187
    optFlags=[["use-console", "C", "show in the console, not graphically"],
 
188
              ["shell-exec", "x", """\
 
189
spawn a new console to show output (implies -C)"""],
 
190
              ]
 
191
 
 
192
def countPys(countl, directory, names):
 
193
    sofar=countl[0]
 
194
    sofar=sofar+len([f for f in names if f.endswith('.py')])
 
195
    countl[0]=sofar
 
196
    return sofar
 
197
 
 
198
def countPysRecursive(path):
 
199
    countl=[0]
 
200
    os.path.walk(path, countPys, countl)
 
201
    return countl[0]
 
202
 
 
203
def run(argv=sys.argv):
 
204
    log.startLogging(file('tkunzip.log', 'w'))
 
205
    opt=TkunzipOptions()
 
206
    try:
 
207
        opt.parseOptions(argv[1:])
 
208
    except usage.UsageError, e:
 
209
        print str(opt)
 
210
        print str(e)
 
211
        sys.exit(1)
 
212
 
 
213
    if opt['use-console']:
 
214
        # this should come before shell-exec to prevent infinite loop
 
215
        return doItConsolicious(opt)              
 
216
    if opt['shell-exec'] or not 'Tkinter' in sys.modules:
 
217
        from distutils import sysconfig
 
218
        from twisted.scripts import tkunzip
 
219
        myfile=tkunzip.__file__
 
220
        exe=os.path.join(sysconfig.get_config_var('prefix'), 'python.exe')
 
221
        return os.system('%s %s --use-console %s' % (exe, myfile,
 
222
                                                     ' '.join(argv[1:])))
 
223
    return doItTkinterly(opt)
 
224
 
 
225
def doItConsolicious(opt):
 
226
    # reclaim stdout/stderr from log
 
227
    sys.stdout = sys.__stdout__
 
228
    sys.stderr = sys.__stderr__
 
229
    if opt['zipfile']:
 
230
        print 'Unpacking documentation...'
 
231
        for n in zipstream.unzipIter(opt['zipfile'], opt['ziptargetdir']):
 
232
            if n % 100 == 0:
 
233
                print n,
 
234
            if n % 1000 == 0:
 
235
                print
 
236
        print 'Done unpacking.'
 
237
        
 
238
    if opt['compiledir']:
 
239
        print 'Compiling to pyc...'
 
240
        import compileall
 
241
        compileall.compile_dir(opt["compiledir"])
 
242
        print 'Done compiling.'
 
243
 
 
244
def doItTkinterly(opt):
 
245
    root=Tkinter.Tk()
 
246
    root.withdraw()
 
247
    root.title('One Moment.')
 
248
    root.protocol('WM_DELETE_WINDOW', reactor.stop)
 
249
    tksupport.install(root)
 
250
    
 
251
    prog=ProgressBar(root, value=0, labelColor="black", width=200)
 
252
    prog.pack()
 
253
 
 
254
    # callback immediately
 
255
    d=defer.succeed(root).addErrback(log.err)
 
256
 
 
257
    def deiconify(root):
 
258
        root.deiconify()
 
259
        return root
 
260
 
 
261
    d.addCallback(deiconify)
 
262
    
 
263
    if opt['zipfile']:
 
264
        uz=Progressor('Unpacking documentation...')
 
265
        max=zipstream.countZipFileChunks(opt['zipfile'], 4096)
 
266
        uz.setBar(prog, max)
 
267
        uz.setIterator(zipstream.unzipIterChunky(opt['zipfile'],
 
268
                                                 opt['ziptargetdir']))
 
269
        d.addCallback(uz.processAll)
 
270
 
 
271
    if opt['compiledir']:
 
272
        comp=Progressor('Compiling to pyc...')
 
273
        comp.setBar(prog, countPysRecursive(opt['compiledir']))
 
274
        comp.setIterator(compiler(opt['compiledir']))
 
275
        d.addCallback(comp.processAll)
 
276
 
 
277
    def stop(ignore):
 
278
        reactor.stop()
 
279
        root.destroy()
 
280
    d.addCallback(stop)
 
281
 
 
282
    reactor.run()
 
283
 
 
284
 
 
285
if __name__=='__main__':
 
286
    run()